// ------------------------------------------------------------------------------------------
// Licensed by Interprise Solutions.
// http://www.InterpriseSolutions.com
// For details on this license please visit  the product homepage at the URL above.
// THE ABOVE NOTICE MUST REMAIN INTACT.
// ------------------------------------------------------------------------------------------
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Globalization;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using System.Xml;
using System.Xml.Linq;
using System.Xml.XPath;
using InterpriseSuiteEcommerceCommon.DTO;
using InterpriseSuiteEcommerceCommon.Extensions;
using InterpriseSuiteEcommerceCommon.InterpriseIntegration.JSONLib;
using InterpriseSuiteEcommerceCommon.InterpriseIntegration.Web;
using InterpriseSuiteEcommerceCommon.Tool;

namespace InterpriseSuiteEcommerceCommon
{
    /// <summary>
    /// Summary description for XSLTExtensions.
    /// </summary>
    public class XSLTExtensionBase
    {
        protected Customer m_ThisCustomer;
        private IEnumerable<ProductImage> TempProductImageForEntityGrid = null;
        private ItemWebOption TempWebOptionSettings = null;

        public class InputValidator
        {
            private String m_RoutineName = String.Empty;

            public InputValidator(String RoutineName)
            {
                m_RoutineName = RoutineName;
            }

            private void ReportError(String ParamName, String ParamValue)
            {
                throw new Exception("Error Calling XSLTExtension Function " + m_RoutineName + ": Invalid value specified for " + ParamName + " (" + CommonLogic.IIF(ParamValue == null, "null", ParamValue) + ")");
            }

            public String ValidateString(String ParamName, String ParamValue)
            {
                if (ParamValue == null)
                {
                    ReportError(ParamName, ParamValue);
                }
                return ParamValue;
            }

            public int ValidateInt(String ParamName, String ParamValue)
            {
                if (ParamValue == null || !CommonLogic.IsInteger(ParamValue))
                {
                    ReportError(ParamName, ParamValue);
                }
                return System.Int32.Parse(ParamValue);
            }

            public Decimal ValidateDecimal(String ParamName, String ParamValue)
            {
                if (ParamValue == null || !CommonLogic.IsNumber(ParamValue))
                {
                    ReportError(ParamName, ParamValue);
                }
                return Localization.ParseDBDecimal(ParamValue);
            }

            public Double ValidateDouble(String ParamName, String ParamValue)
            {
                if (ParamValue == null || !CommonLogic.IsNumber(ParamValue))
                {
                    ReportError(ParamName, ParamValue);
                }
                return Localization.ParseDBDouble(ParamValue);
            }

            public bool ValidateBool(String ParamName, String ParamValue)
            {
                if (ParamValue == null)
                {
                    ReportError(ParamName, ParamValue);
                }
                if ("TRUE".Equals(ParamValue, StringComparison.InvariantCultureIgnoreCase) ||
                    "YES".Equals(ParamValue, StringComparison.InvariantCultureIgnoreCase) ||
                    "1".Equals(ParamValue, StringComparison.InvariantCultureIgnoreCase))                
                {
                    return true;
                }
                return false;
            }

            public DateTime ValidateDateTime(String ParamName, String ParamValue)
            {
                DateTime dt = System.DateTime.MinValue;
                if (ParamValue == null)
                {
                    ReportError(ParamName, ParamValue);
                }
                try
                {
                    dt = Localization.ParseDBDateTime(ParamValue);
                }
                catch
                {
                    ReportError(ParamName, ParamValue);
                }
                return dt;
            }

        }

        public XSLTExtensionBase(Customer cust, int SkinID)
        {
            m_ThisCustomer = cust;
            if (m_ThisCustomer == null)
            {
                try
                {
                    m_ThisCustomer = ((InterpriseSuiteEcommercePrincipal)HttpContext.Current.User).ThisCustomer;
                }
                catch { }
                if (m_ThisCustomer == null)
                {
                    m_ThisCustomer = Customer.MakeAnonymous(); 
                }
            }
        }

        public virtual void LoadWebOptionSetting(string itemCode)
        {
            TempWebOptionSettings = ItemWebOption.GetWebOption(itemCode);
        }

        public virtual string SetTrace(string sTraceName)
        {
            InputValidator IV = new InputValidator("SetTrace");
            String TraceName = IV.ValidateString("TraceName", sTraceName);
            if (!HttpContext.Current.Items.Contains("XmlPackageTracePoint"))
            {
                HttpContext.Current.Items.Add("XmlPackageTracePoint", TraceName);
            }
            else
            {
                HttpContext.Current.Items["XmlPackageTracePoint"] = TraceName;
            }
            return String.Empty;
        }

        public virtual String GetRootEntityContextOfPage(String sEntityName)
        {
            InputValidator IV = new InputValidator("GetRootEntityContextOfPage");
            String EntityName = IV.ValidateString("EntityName", sEntityName);

            EntityHelper catHelper = AppLogic.LookupHelper(EntityName);
            String ProductIDQS = CommonLogic.QueryStringCanBeDangerousContent("ProductID");
            String EntityIDQS = CommonLogic.QueryStringCanBeDangerousContent(EntityName + "ID");
            if (CommonLogic.QueryStringCanBeDangerousContent("EntityID").Length != 0)
            {
                EntityIDQS = CommonLogic.QueryStringCanBeDangerousContent("EntityID");
            }
            String EntityIDCookie = CommonLogic.IIF(CommonLogic.CookieCanBeDangerousContent("LastViewedEntityName", true) == EntityName, CommonLogic.CookieCanBeDangerousContent("LastViewedEntityInstanceID",true), String.Empty);
            String EntityIDActual = String.Empty;
            String EntityIDRoot = String.Empty;
            if (ProductIDQS.Length != 0)
            {
                // we have a product context, did they get there from a Entity/subcat page or not. cookie is set if so.
                if (EntityIDCookie.Length != 0)
                {
                    EntityIDActual = EntityIDCookie;
                }
                else
                {
                    EntityIDActual = AppLogic.GetFirstProductEntityID(catHelper, ProductIDQS, false);
                }
            }
            else
            {
                if (EntityIDQS.Length != 0)
                {
                    EntityIDActual = EntityIDQS;
                }
            }
            EntityIDRoot = catHelper.GetRootEntity(EntityIDActual);
            return EntityIDRoot.ToString();
        }

        public virtual String GetLastEntityContextOfPage(String sEntityName)
        {
            InputValidator IV = new InputValidator("GetRootEntityContextOfPage");
            String EntityName = IV.ValidateString("EntityName", sEntityName);

            EntityHelper catHelper = AppLogic.LookupHelper(EntityName);
            int ProductIDQS = CommonLogic.QueryStringUSInt("ProductID");
            String EntityIDQS = CommonLogic.QueryStringCanBeDangerousContent(EntityName + "ID");
            if (CommonLogic.QueryStringCanBeDangerousContent("EntityID").Length != 0)
            {
                EntityIDQS = CommonLogic.QueryStringCanBeDangerousContent("EntityID");
            }
            String EntityIDCookie = CommonLogic.IIF(CommonLogic.CookieCanBeDangerousContent("LastViewedEntityName", true) == EntityName, CommonLogic.CookieCanBeDangerousContent("LastViewedEntityInstanceID", true), String.Empty);
            String EntityID = "0";
            if (ProductIDQS != 0)
            {
                // we have a product context, did they get there from a Entity/subcat page or not. cookie is set if so.
                string _itemCode = InterpriseHelper.GetInventoryItemCode(ProductIDQS);
                if (EntityIDCookie.Length != 0)
                {
                    //but first! check it is a valid entity for a product, if yes use it, otherwise provide the right entityid
                    ArrayList alE = EntityHelper.GetProductEntityList(_itemCode, EntityName);
                    if (alE.IndexOf(Localization.ParseNativeInt(EntityIDCookie)) > -1)
                    {
                        EntityID = EntityIDCookie;
                    }
                    else
                    {
                        EntityID = EntityHelper.GetProductsFirstEntity(_itemCode, EntityName).ToString();
                    }
                }
            }
            else
            {
                if (EntityIDQS.Length != 0)
                {
                    EntityID = EntityIDQS;
                }
            }
            return EntityID.ToString();
        }

        public virtual String AjaxShippingEstimator(String sVariantID)
        {
            InputValidator IV = new InputValidator("SetTrace");
            int VariantID = IV.ValidateInt("VariantID", sVariantID);

            StringBuilder tmpS = new StringBuilder(1024);
            tmpS.Append("<div id=\"AjaxShipping\">");

            tmpS.Append("<div id=\"AjaxShippingCountry\">");
            tmpS.Append("<div class=\"AjaxShippingLabel\">");
            tmpS.Append(AppLogic.GetString("order.cs.22", ThisCustomer.SkinID, ThisCustomer.LocaleSetting));
            tmpS.Append("</div>");
            DataSet dscountry = DB.GetDS("select * from country with (NOLOCK) order by DisplayOrder,Name", AppLogic.CachingOn, System.DateTime.Now.AddMinutes(AppLogic.CacheDurationMinutes()));
            if (dscountry.Tables[0].Rows.Count == 1)
            {
                DataRow row = dscountry.Tables[0].Rows[0];
                tmpS.Append("<span id=\"AjaxShippingCountrySingleValue\">");
                tmpS.Append("<input type=\"hidden\" name=\"Country\" id=\"Country\" value=\"" + DB.RowField(row, "Name").Replace("\"", "") + "\">");
                tmpS.Append(DB.RowField(row, "Name"));
                tmpS.Append("</span>");
            }
            else
            {
                tmpS.Append("<select name=\"Country\" id=\"Country\" onchange=\"javascript:getShipping();\">");
                foreach (DataRow row in dscountry.Tables[0].Rows)
                {
                    tmpS.Append("<option value=\"" + DB.RowField(row, "Name").Replace("\"", "") + "\">" + DB.RowField(row, "Name") + "</option>");
                }
                tmpS.Append("</select>");
            }
            dscountry.Dispose();
            tmpS.Append("</div>");

            tmpS.Append("<div id=\"AjaxShippingState\">");
            tmpS.Append("<div class=\"AjaxShippingLabel\">");
            tmpS.Append(AppLogic.GetString("order.cs.20", ThisCustomer.SkinID, ThisCustomer.LocaleSetting));
            tmpS.Append("</div>");
            DataSet dsstate = DB.GetDS("select * from state with (NOLOCK) order by DisplayOrder,Name", AppLogic.CachingOn, System.DateTime.Now.AddMinutes(AppLogic.CacheDurationMinutes()));
            if (dsstate.Tables[0].Rows.Count == 1)
            {
                DataRow row = dsstate.Tables[0].Rows[0];
                tmpS.Append("<input type=\"hidden\" name=\"State\" id=\"State\" value=\"" + DB.RowField(row, "Name").Replace("\"", "") + "\">");
                tmpS.Append("<span id=\"AjaxShippingStateSingleValue\">");
                tmpS.Append(DB.RowField(row, "Name"));
                tmpS.Append("</span>");
            }
            else
            {
                tmpS.Append("<select name=\"State\" id=\"State\" onchange=\"javascript:getShipping();\">");
                foreach (DataRow row in dsstate.Tables[0].Rows)
                {
                    tmpS.Append("<option value=\"" + DB.RowField(row, "Abbreviation") + "\">" + DB.RowField(row, "Name") + "</option>");
                }
                tmpS.Append("</select>");
            }
            dsstate.Dispose();
            tmpS.Append("</div>");

            tmpS.Append("<div id=\"AjaxShippingZip\">");
            tmpS.Append("<div class=\"AjaxShippingLabel\">");
            tmpS.Append(AppLogic.GetString("order.cs.21", ThisCustomer.SkinID, ThisCustomer.LocaleSetting));
            tmpS.Append("</div>");
            tmpS.Append("<input class=\"AjaxShippingZip\" type=\"text\" size=\"5\" maxlength=\"6\" id=\"PostalCode\" name=\"PostalCode\" onkeyup=\"javascript:getShipping();\"/>");
            tmpS.Append("</div>");

            tmpS.Append("<div id=\"AjaxShippingEstimate\">");
            tmpS.Append("<div class=\"AjaxShippingLabel\">Shipping Estimate:</div>");
            tmpS.Append("<p id=\"ShipQuote\"></p>");
            tmpS.Append("</div>");

            tmpS.Append("</div>");
            return tmpS.ToString();
        }
        
        public virtual string RemoteUrl(string sURL)
        {
            InputValidator IV = new InputValidator("RemoteUrl");
            String URL = IV.ValidateString("URL", sURL);
            return CommonLogic.AspHTTP(URL, 30);
        }

        public string StripHtml(String sTheString)
        {
            InputValidator IV = new InputValidator("StripHtml");
            String TheString = IV.ValidateString("TheString", sTheString);
            return AppLogic.StripHtml(TheString);
        }

        public virtual string PagingControl(string sBaseURL, String sPageNum, String sNumPages)
        {
            InputValidator IV = new InputValidator("PagingControl");
            String BaseURL = IV.ValidateString("BaseURL", sBaseURL);
            int PageNum = IV.ValidateInt("PageNum", sPageNum);
            int NumPages = IV.ValidateInt("NumPage", sNumPages);

            bool IsAttribute = CommonLogic.GetThisPageName(false).ToLower().Equals("showattribute.aspx");
            string EntityName = InterpriseSuiteEcommerceCommon.CommonLogic.QueryStringCanBeDangerousContent("EntityName");
            string EntityID = InterpriseSuiteEcommerceCommon.CommonLogic.QueryStringCanBeDangerousContent("EntityID");
            string AtttributeParam = string.Empty;

            if (IsAttribute)
            { IsAttribute = EntityName.Length > 0 && EntityID.Length > 0; }

            if (IsAttribute)
            { AtttributeParam = string.Concat("&", "EntityID=", EntityID, "&", "EntityName=", EntityName); }


            string result = String.Empty;
            if (NumPages < 2)
            {
                return "";
            }

            if (BaseURL.Length == 0)
            {
                BaseURL = CommonLogic.GetThisPageName(false) + "?" + CommonLogic.ServerVariables("QUERY_STRING");
            }
            if (PageNum == 0)
            {
                PageNum = CommonLogic.QueryStringUSInt("PageNum");
            }
            if (PageNum == 0)
            {
                PageNum = 1;
            }

            String Separator = "?";
            if (BaseURL.IndexOf("?") != -1)
            {
                Separator = "&";
            }

            StringBuilder tmpS = new StringBuilder(4096);
            tmpS.Append("Page: ");

            if (PageNum > 1)
            {
                if (BaseURL.IndexOf("pagenum=", StringComparison.InvariantCultureIgnoreCase) == -1)
                {
                    tmpS.Append("<a href=\"" + BaseURL + Separator + "pagenum=" + Convert.ToString(PageNum - 1) + AtttributeParam + "\">");
                    tmpS.Append("<img border=\"0\" src=\"" + AppLogic.LocateImageURL("skins/skin_" + ThisCustomer.SkinID.ToString() + "/images/Redarrowleft.gif") + "\">");
                    tmpS.Append("</a>&nbsp;");
                }
                else
                {
                    tmpS.Append("<a href=\"" + Regex.Replace(BaseURL, @"pagenum=\w*", "pagenum=" + Convert.ToString(PageNum - 1) + AtttributeParam, RegexOptions.Compiled) + "\">");
                    tmpS.Append("<img border=\"0\" src=\"" + AppLogic.LocateImageURL("skins/skin_" + ThisCustomer.SkinID.ToString() + "/images/Redarrowleft.gif") + "\">");
                    tmpS.Append("</a>&nbsp;");
                }
            }

            for (int i = 1; i <= NumPages; i++)
            {
                if (i == PageNum)
                {
                    tmpS.Append(i.ToString());
                    tmpS.Append(" ");
                }
                else
                {
                    tmpS.Append("<a class=\"PageNumber\" href=\"");
                    if (BaseURL.IndexOf("pagenum=", StringComparison.InvariantCultureIgnoreCase) == -1)
                    {
                        tmpS.Append(BaseURL);
                        tmpS.Append(Separator);
                        tmpS.Append("pagenum=");
                        tmpS.Append(i.ToString());
                        tmpS.Append(AtttributeParam);
                    }
                    else
                    {
                        tmpS.Append(Regex.Replace(BaseURL, @"pagenum=\w*", "pagenum=" + i.ToString(), RegexOptions.Compiled));
                    }
                    tmpS.Append("\">");
                    tmpS.Append(i.ToString());
                    tmpS.Append("</a>");
                    tmpS.Append(" ");
                }
            }

            if (PageNum < NumPages)
            {
                if (BaseURL.IndexOf("pagenum=", StringComparison.InvariantCultureIgnoreCase) == -1)
                {
                    tmpS.Append("&nbsp;<a href=\"" + BaseURL + Separator + "pagenum=" + Convert.ToString(PageNum + 1) + AtttributeParam + "\">");
                    tmpS.Append("<img border=\"0\" src=\"skins/skin_" + ThisCustomer.SkinID.ToString() + "/images/Redarrow.gif\">");
                    tmpS.Append("</a>");
                }
                else
                {
                    tmpS.Append("&nbsp;<a href=\"" + Regex.Replace(BaseURL, @"pagenum=\w*", "pagenum=" + Convert.ToString(PageNum + 1) + AtttributeParam, RegexOptions.Compiled) + "\">");
                    tmpS.Append("<img border=\"0\" src=\"skins/skin_" + ThisCustomer.SkinID.ToString() + "/images/Redarrow.gif\">");
                    tmpS.Append("</a>");
                }
            }

            result = tmpS.ToString();
            return result;
        }

        public virtual string PagingControl(string sBaseURL, String sPageNum, String sNumPages, string sSortNum)
        {
            InputValidator IV = new InputValidator("PagingControl");
            String BaseURL = IV.ValidateString("BaseURL", sBaseURL);
            int PageNum = IV.ValidateInt("PageNum", sPageNum);
            int NumPages = IV.ValidateInt("NumPage", sNumPages);
            string SortParam = IV.ValidateString("SortNum", sSortNum);

            if (SortParam.Length != 0)
            {
                SortParam = "&sort=" + SortParam;
            }

            bool IsAttribute = CommonLogic.GetThisPageName(false).ToLower().Equals("showattribute.aspx");
            string EntityName = InterpriseSuiteEcommerceCommon.CommonLogic.QueryStringCanBeDangerousContent("EntityName");
            string EntityID = InterpriseSuiteEcommerceCommon.CommonLogic.QueryStringCanBeDangerousContent("EntityID");
            string AtttributeParam = string.Empty;

            if (IsAttribute)
            { IsAttribute = EntityName.Length > 0 && EntityID.Length > 0; }

            if (IsAttribute)
            { AtttributeParam = string.Concat("&", "EntityID=", EntityID, "&", "EntityName=", EntityName); }


            string result = String.Empty;
            if (NumPages < 2)
            {
                return "";
            }

            if (BaseURL.Length == 0)
            {
                BaseURL = CommonLogic.GetThisPageName(false) + "?" + CommonLogic.ServerVariables("QUERY_STRING");
            }
            if (PageNum == 0)
            {
                PageNum = CommonLogic.QueryStringUSInt("PageNum");
            }
            if (PageNum == 0)
            {
                PageNum = 1;
            }

            String Separator = "?";
            if (BaseURL.IndexOf("?") != -1)
            {
                Separator = "&";
            }

            StringBuilder tmpS = new StringBuilder(4096);

            if (PageNum > 1)
            {
                if (BaseURL.IndexOf("pagenum=", StringComparison.InvariantCultureIgnoreCase) == -1)
                {
                    tmpS.Append("<a class=\"PagingPrev\" title=\"previous\" href=\"" + BaseURL + Separator + "pagenum=" + Convert.ToString(PageNum - 1) + AtttributeParam + SortParam + "\">");
                    tmpS.Append("</a>");
                }
                else
                {
                    tmpS.Append("<a class=\"PagingPrev\" title=\"previous\" href=\"" + Regex.Replace(BaseURL, @"pagenum=\w*", "pagenum=" + Convert.ToString(PageNum - 1) + AtttributeParam, RegexOptions.Compiled) + SortParam + "\">");
                    tmpS.Append("</a>");
                }
            }
            else
            {
                tmpS.Append("<a class=\"PagingPrevInactive\" href=\"javascript:void(0)\">");
                tmpS.Append("</a>");
            }

            for (int i = 1; i <= NumPages; i++)
            {
                if (i == PageNum)
                {
                    tmpS.Append("<a class=\"PagingActive\">");
                    tmpS.Append(i.ToString());
                    tmpS.Append("</a>");
                }
                else
                {
                    tmpS.Append("<a class=\"PagingNum\" href=\"");
                    if (BaseURL.IndexOf("pagenum=", StringComparison.InvariantCultureIgnoreCase) == -1)
                    {
                        tmpS.Append(BaseURL);
                        tmpS.Append(Separator);
                        tmpS.Append("pagenum=");
                        tmpS.Append(i.ToString());
                        tmpS.Append(AtttributeParam);
                    }
                    else
                    {
                        tmpS.Append(Regex.Replace(BaseURL, @"pagenum=\w*", "pagenum=" + i.ToString(), RegexOptions.Compiled));
                    }

                    tmpS.Append(SortParam);
                    tmpS.Append("\">");
                    tmpS.Append(i.ToString());
                    tmpS.Append("</a>");
                }
            }

            if (PageNum < NumPages)
            {
                if (BaseURL.IndexOf("pagenum=", StringComparison.InvariantCultureIgnoreCase) == -1)
                {
                    tmpS.Append("<a class=\"PagingNext\" title=\"next\" href=\"" + BaseURL + Separator + "pagenum=" + Convert.ToString(PageNum + 1) + AtttributeParam + SortParam + "\">");
                    tmpS.Append("</a>");
                }
                else
                {
                    tmpS.Append("<a class=\"PagingNext\" title=\"next\" href=\"" + Regex.Replace(BaseURL, @"pagenum=\w*", "pagenum=" + Convert.ToString(PageNum + 1) + AtttributeParam, RegexOptions.Compiled) + SortParam + "\">");
                    tmpS.Append("</a>");
                }
            }
            else
            {
                tmpS.Append("<a class=\"PagingNextInactive\" href=\"javascript:void(0)\">");
                tmpS.Append("</a>");
            }
            result = tmpS.ToString();
            return result;
        }

        public virtual string SortingControl()
        {
            var xmlPackage = new XmlPackage2("productsorting.xml.config");
            string output = xmlPackage.TransformString();
            
            return output.ToString();
        }

        #region "ProductShareConrol"
        public virtual string ProductShareControl(string productID, string categoryID, string productName, string productUrl, string productDesc)
        {
            string sOutput = string.Empty;

            if (!this.IsUsingHelperTemplate) { return sOutput; }

            var xml = new System.Xml.Linq.XElement(DomainConstants.XML_ROOT_NAME);
            xml.Add(new System.Xml.Linq.XElement(DomainConstants.XML_SECTION_TYPE, XMLProductSectionType.DISPLAY_SHAREBOX));
            xml.Add(new System.Xml.Linq.XElement("ProductID", productID));
            xml.Add(new System.Xml.Linq.XElement("CategoryID", categoryID));
            xml.Add(new System.Xml.Linq.XElement("ProductName", productName));
            xml.Add(new System.Xml.Linq.XElement("ProductUrl", productUrl));
            xml.Add(new System.Xml.Linq.XElement("ProductDesc", productDesc));

            var xmlpackage = new XmlPackage2(this.XmlPackageHelperTemplate, xml);
            sOutput = xmlpackage.TransformString();

            return sOutput;
        }
        #endregion

        #region "ProductCommentsControl"
        public virtual string ProductCommentsControl(string productUrl)
        {
            string sOutput = string.Empty;

            if (!this.IsUsingHelperTemplate) { return sOutput; }

            var xml = new System.Xml.Linq.XElement(DomainConstants.XML_ROOT_NAME);
            xml.Add(new System.Xml.Linq.XElement(DomainConstants.XML_SECTION_TYPE, XMLProductSectionType.DISPLAY_COMMENTBOX));
            xml.Add(new System.Xml.Linq.XElement("ProductUrl", productUrl));

            var xmlpackage = new XmlPackage2(this.XmlPackageHelperTemplate, xml);
            sOutput = xmlpackage.TransformString();

            return sOutput;
        }
        #endregion

        //Public Methods
        public Customer ThisCustomer
        {
            get
            {
                return m_ThisCustomer;
            }
        }

        public virtual string SkinID()
        {
            return ThisCustomer.SkinID.ToString();
        }

        public virtual void SendMail(String sSubject, String sBody, String sUseHtml, String sToAddress)
        {
            InputValidator IV = new InputValidator("SendMail");
            String Subject = IV.ValidateString("Subject", sSubject);
            String Body = IV.ValidateString("Body", sBody);
            bool UseHtml = IV.ValidateBool("UseHtml", sUseHtml);
            String ToAddress = IV.ValidateString("ToAddress", sToAddress);
            String Srv = AppLogic.MailServer().Trim();
            if (Srv.Length != 0 && Srv != AppLogic.ro_TBD)
            {
                AppLogic.SendMail(Subject, Body, UseHtml, AppLogic.AppConfig("MailMe_FromAddress"), AppLogic.AppConfig("MailMe_FromAddress"), ToAddress, ToAddress, String.Empty, Srv);
            }
        }

        public virtual string CustomerID()
        {
            string result = String.Empty;
            if (ThisCustomer != null)
            {
                result = ThisCustomer.CustomerCode.ToString();
            }
            else
            {
                result = String.Empty;
            }
            return result;
        }

        public virtual string User_Name()
        {
            string result = String.Empty;
            if (!ThisCustomer.IsRegistered)
            {
                result = String.Empty;
            }
            else
            {
                if (AppLogic.AppConfigBool("ForceSignoutOnOrderCompletion") && CommonLogic.QueryStringCanBeDangerousContent("OrderNumber", true) != string.Empty)
                {
                    result = string.Empty;
                }
                else
                {
                    result = AppLogic.GetString("skinbase.cs.1", ThisCustomer.SkinID, ThisCustomer.LocaleSetting) + " <a class=\"username\" href=\"account.aspx\">" + HttpUtility.HtmlEncode(ThisCustomer.FullName) + "</a>"; // +CommonLogic.IIF(ThisCustomer.CustomerLevelID != 0, "&nbsp;(" + ThisCustomer.CustomerLevelName + ")", "");
                }
                
            }
            return result;
        }

        public virtual string User_Menu_Name()
        {
            string result = String.Empty;
            if (!ThisCustomer.IsRegistered)
            {
                result = AppLogic.GetString("skinbase.cs.7", ThisCustomer.SkinID, ThisCustomer.LocaleSetting);
            }
            else
            {
                result = ThisCustomer.FullName;
            }
            return result;
        }

        public virtual string StoreVersion(String sNotUsed)
        {
            return CommonLogic.GetVersion();
        }

        public virtual string OnLiveServer(String sNotUsed)
        {
            return AppLogic.OnLiveServer().ToString().ToLowerInvariant();
        }

        //The following functions are for backward compatibility with Parser functions only and 
        //should not be used in XmlPackage transforms because the output invalid XML when using the IncludeATag
        //Newer fucntions that produce well formed output are below
        public virtual string ManufacturerLink(String sManufacturerID, String sSEName, String sIncludeATag)
        {
            InputValidator IV = new InputValidator("ManufacturerLink");
            String ManufacturerID = IV.ValidateString("ManufacturerID", sManufacturerID);
            String SEName = IV.ValidateString("SEName", sSEName);
            bool IncludeATag = IV.ValidateBool("IncludeATag", sIncludeATag);
            string result = String.Empty;
            result = SE.MakeManufacturerLink(ManufacturerID, SEName);
            if (IncludeATag)
            {
                result = "<a href=\"" + result + "\" />";
            }
            return result;
        }

        public virtual string CategoryLink(String sCategoryID, String sSEName, String sIncludeATag)
        {
            // (!CategoryLink CategoryID="N" SEName="xxx" IncludeATag="true/false"!)
            InputValidator IV = new InputValidator("CategoryLink");
            String CategoryID = IV.ValidateString("CategoryID", sCategoryID);
            String SEName = IV.ValidateString("SEName", sSEName);
            bool IncludeATag = IV.ValidateBool("IncludeATag", sIncludeATag);
            string result = String.Empty;
            result = SE.MakeCategoryLink(CategoryID, SEName);
            if (IncludeATag)
            {
                result = "<a href=\"" + result + "\" />";
            }
            return result;
        }

        public virtual string SectionLink(String sDepartmentID, String sSEName, String sIncludeATag)
        {
            // (!SectionLink DepartmentID="N" SEName="xxx" IncludeATag="true/false"!)
            InputValidator IV = new InputValidator("SectionLink");
            String DepartmentID = IV.ValidateString("SectionID", sDepartmentID);
            String SEName = IV.ValidateString("SEName", sSEName);
            bool IncludeATag = IV.ValidateBool("IncludeATag", sIncludeATag);
            string result = String.Empty;
            result = SE.MakeSectionLink(DepartmentID, SEName);
            if (IncludeATag)
            {
                result = "<a href=\"" + result + "\" />";
            }
            return result;
        }

        public virtual string LibraryLink(String sLibraryID, String sSEName, String sIncludeATag)
        {
            // (!LibraryLink LibraryID="N" SEName="xxx" IncludeATag="true/false"!)
            InputValidator IV = new InputValidator("LibraryLink");
            String LibraryID = IV.ValidateString("LibraryID", sLibraryID);
            String SEName = IV.ValidateString("SEName", sSEName);
            bool IncludeATag = IV.ValidateBool("IncludeATag", sIncludeATag);
            string result = String.Empty;
            result = SE.MakeEntityLink("Library", LibraryID, SEName);
            if (IncludeATag)
            {
                result = "<a href=\"" + result + "\" />";
            }
            return result;
        }

        public virtual string ProductLink(String sProductID, String sSEName, String sIncludeATag)
        {
            // (!ProductLink ProductID="N" SEName="xxx" IncludeATag="true/false"!)
            InputValidator IV = new InputValidator("ProductLink");
            String ProductID = IV.ValidateString("ProductID", sProductID);
            String SEName = IV.ValidateString("SEName", sSEName);
            bool IncludeATag = IV.ValidateBool("IncludeATag", sIncludeATag);
            string result = String.Empty;
            result = SE.MakeProductLink(ProductID, SEName);
            if (IncludeATag)
            {
                result = "<a href=\"" + result + "\" />";
            }
            return result;
        }

        public virtual string DocumentLink(String sDocumentID, String sSEName, String sIncludeATag)
        {
            // (!DocumentLink DocumentID="N" SEName="xxx" IncludeATag="true/false"!)
            InputValidator IV = new InputValidator("DocumentLink");
            String DocumentID = IV.ValidateString("DocumentID", sDocumentID);
            String SEName = IV.ValidateString("SEName", sSEName);
            bool IncludeATag = IV.ValidateBool("IncludeATag", sIncludeATag);
            string result = String.Empty;
            result = SE.MakeObjectLink("Document", DocumentID, SEName);
            if (IncludeATag)
            {
                result = "<a href=\"" + result + "\">";
            }
            return result;
        }

        public virtual string ProductandCategoryLink(String sProductID, String sSEName, String sCategoryID, String sIncludeATag)
        {
            // (!ProductAndCategoryLink ProductID="N" CategoryID="M" SEName="xxx" IncludeATag="true/false"!)
            InputValidator IV = new InputValidator("ProductandCategoryLink");
            String ProductID = IV.ValidateString("ProductID", sProductID);
            String CategoryID = IV.ValidateString("CategoryID", sCategoryID);
            String SEName = IV.ValidateString("SEName", sSEName);
            bool IncludeATag = IV.ValidateBool("IncludeATag", sIncludeATag);
            string result = String.Empty;
            result = SE.MakeProductAndCategoryLink(ProductID, CategoryID, SEName);
            if (IncludeATag)
            {
                result = "<a href=\"" + result + "\">";
            }
            return result;
        }

        public virtual string ProductandSectionLink(String sProductID, String sSEName, String sDepartmentID, String sIncludeATag)
        {
            // (!ProductAndSectionLink ProductID="N" DepartmentID="M" SEName="xxx" IncludeATag="true/false"!)
            InputValidator IV = new InputValidator("ProductandSectionLink");
            String ProductID = IV.ValidateString("ProductID", sProductID);
            String DepartmentID = IV.ValidateString("SectionID", sDepartmentID);
            String SEName = IV.ValidateString("SEName", sSEName);
            bool IncludeATag = IV.ValidateBool("IncludeATag", sIncludeATag);
            string result = String.Empty;
            result = SE.MakeProductAndSectionLink(ProductID, DepartmentID, SEName);
            if (IncludeATag)
            {
                result = "<a href=\"" + result + "\">";
            }
            return result;
        }

        public virtual string ProductandManufacturerLink(String sProductID, String sSEName, String sManufacturerID, String sIncludeATag)
        {
            InputValidator IV = new InputValidator("ProductandManufacturerLink");
            String ProductID = IV.ValidateString("ProductID", sProductID);
            String ManufacturerID = IV.ValidateString("ManufacturerID", sManufacturerID);
            String SEName = IV.ValidateString("SEName", sSEName);
            bool IncludeATag = IV.ValidateBool("IncludeATag", sIncludeATag);
            string result = String.Empty;
            result = SE.MakeProductAndEntityLink("Manufacturer", ProductID, ManufacturerID, SEName);
            if (IncludeATag)
            {
                result = "<a href=\"" + result + "\">";
            }
            return result;
        }

        public virtual string DocumentandLibraryLink(String sDocumentID, String sSEName, String sLibraryID, String sIncludeATag)
        {
            InputValidator IV = new InputValidator("DocumentandLibraryLink");
            String DocumentID = IV.ValidateString("DocumentID", sDocumentID);
            String LibraryID = IV.ValidateString("LibraryID", sLibraryID);
            String SEName = IV.ValidateString("SEName", sSEName);
            bool IncludeATag = IV.ValidateBool("IncludeATag", sIncludeATag);
            string result = String.Empty;
            result = SE.MakeObjectAndEntityLink("Document", "Library", DocumentID, LibraryID, SEName);
            if (IncludeATag)
            {
                result = "<a href=\"" + result + "\">";
            }
            return result;
        }

        public virtual string EntityLink(String sEntityID, String sSEName, String sEntityName, String sIncludeATag)
        {
            InputValidator IV = new InputValidator("EntityLink");
            String SEName = IV.ValidateString("SEName", sSEName);
            String EntityName = IV.ValidateString("EntityName", sEntityName);
            String EntityID = IV.ValidateString("EntityID", sEntityID);
            bool IncludeATag = IV.ValidateBool("IncludeATag", sIncludeATag);
            string result = String.Empty;
            result = SE.MakeEntityLink(EntityName, EntityID, SEName);
            if (IncludeATag)
            {
                result = "<a href=\"" + result + "\">";
            }
            return result;
        }

        public virtual string ObjectLink(String sObjectID, String sSEName, String sObjectName, String sIncludeATag)
        {
            InputValidator IV = new InputValidator("ObjectLink");
            String ObjectID = IV.ValidateString("ObjectID", sObjectID);
            String ObjectName = IV.ValidateString("ObjectName", sObjectName);
            String SEName = IV.ValidateString("SEName", sSEName);
            bool IncludeATag = IV.ValidateBool("IncludeATag", sIncludeATag);
            string result = String.Empty;
            result = SE.MakeObjectLink(ObjectName, ObjectID, SEName);
            if (IncludeATag)
            {
                result = "<a href=\"" + result + "\">";
            }
            return result;
        }

        public virtual string ProductandEntityLink(String sProductID, String sSEName, String sEntityID, String sEntityName, String sIncludeATag)
        {
            InputValidator IV = new InputValidator("ProductandEntityLink");
            String ProductID = IV.ValidateString("ProductID", sProductID);
            String EntityID = IV.ValidateString("EntityID", sEntityID);
            String EntityName = IV.ValidateString("EntityName", sEntityName);
            String SEName = IV.ValidateString("SEName", sSEName);
            bool IncludeATag = IV.ValidateBool("IncludeATag", sIncludeATag);
            string result = String.Empty;
            result = SE.MakeProductAndEntityLink(EntityName, ProductID, EntityID, SEName);
            if (IncludeATag)
            {
                result = "<a href=\"" + result + "\">";
            }
            return result;
        }

        public virtual string ManufacturerLink(string sManufacturerID, string sSEName, string sIncludeATag, string sTagInnerText)
        {
            // (!ManufacturerLink ManufacturerID="N" SEName="xxx" IncludeATag="true/false"!)
            InputValidator IV = new InputValidator("ManufacturerLink");
            String ManufacturerID = IV.ValidateString("ManufacturerID", sManufacturerID);
            String SEName = IV.ValidateString("SEName", sSEName);
            bool IncludeATag = IV.ValidateBool("IncludeATag", sIncludeATag);
            String TagInnerText = IV.ValidateString("TagInnerText", sTagInnerText);
            string result = String.Empty;
            result = SE.MakeManufacturerLink(ManufacturerID, SEName);
            if (IncludeATag)
            {
                result = "<a href=\"" + result + "\" />" + TagInnerText + "</a>";
            }
            return result;
        }

        public virtual string CategoryLink(string sCategoryID, string sSEName, string sIncludeATag, string sTagInnerText)
        {
            // (!CategoryLink CategoryID="N" SEName="xxx" IncludeATag="true/false"!)
            InputValidator IV = new InputValidator("CategoryLink");
            String CategoryID = IV.ValidateString("CategoryID", sCategoryID);
            String SEName = IV.ValidateString("SEName", sSEName);
            bool IncludeATag = IV.ValidateBool("IncludeATag", sIncludeATag);
            String TagInnerText = IV.ValidateString("TagInnerText", sTagInnerText);
            string result = String.Empty;
            result = SE.MakeCategoryLink(CategoryID, SEName);
            if (IncludeATag)
            {
                result = "<a href=\"" + result + "\" />" + TagInnerText + "</a>";
            }
            return result;
        }

        public virtual string AttributeLink(string sAttributeID, string sSEName, string sIncludeATag, string sTagInnerText)
        {
            // (!AttributeLink AttributeID="N" SEName="xxx" IncludeATag="true/false"!)
            InputValidator IV = new InputValidator("AttributeLink");
            String AttributeID = IV.ValidateString("AttributeID", sAttributeID);
            String SEName = IV.ValidateString("SEName", sSEName);
            bool IncludeATag = IV.ValidateBool("IncludeATag", sIncludeATag);
            String TagInnerText = IV.ValidateString("TagInnerText", sTagInnerText);
            string result = String.Empty;
            result = SE.MakeAttributeLink(AttributeID, SEName);
            if (IncludeATag)
            {
                result = "<a href=\"" + result + "\" />" + TagInnerText + "</a>";
            }
            return result;
        }

        public virtual string SectionLink(string sDepartmentID, String sSEName, String sIncludeATag, string sTagInnerText)
        {
            // (!SectionLink SectionID="N" SEName="xxx" IncludeATag="true/false"!)
            InputValidator IV = new InputValidator("SectionLink");
            String DepartmentID = IV.ValidateString("SectionID", sDepartmentID);
            String SEName = IV.ValidateString("SEName", sSEName);
            bool IncludeATag = IV.ValidateBool("IncludeATag", sIncludeATag);
            String TagInnerText = IV.ValidateString("TagInnerText", sTagInnerText);
            string result = String.Empty;
            result = SE.MakeSectionLink(DepartmentID, SEName);
            if (IncludeATag)
            {
                result = "<a href=\"" + result + "\" />" + TagInnerText + "</a>";
            }
            return result;
        }

        public virtual string ProductLink(string sProductID, String sSEName, String sIncludeATag, string sTagInnerText)
        {
            // (!ProductLink ProductID="N" SEName="xxx" IncludeATag="true/false"!)
            InputValidator IV = new InputValidator("ProductLink");
            String ProductID = IV.ValidateString("ProductID", sProductID);
            String SEName = IV.ValidateString("SEName", sSEName);
            bool IncludeATag = IV.ValidateBool("IncludeATag", sIncludeATag);
            String TagInnerText = IV.ValidateString("TagInnerText", sTagInnerText);
            string result = String.Empty;
            result = SE.MakeProductLink(ProductID, SEName);
            if (IncludeATag)
            {
                result = "<a href=\"" + result + "\" />" + TagInnerText + "</a>";
            }
            return result;
        }

        public virtual string GetSubstituteProducts(string sitemCode)
        {
            if (this.IsUsingHelperTemplate && CurrentContext.IsRequestingFromMobileMode(ThisCustomer))
            {
                return GetSubstituteProducts(sitemCode, true);
            }

            InputValidator IV = new InputValidator("SubstituteProducts");
            string ProductID = IV.ValidateString("ItemCode", sitemCode);
            return InterpriseHelper.ShowInventorySubstituteOptions(sitemCode, 100, true, string.Empty, ThisCustomer);
        }

        /// <summary>
        /// This is used to automatically invoke the design from xmlpackage
        /// </summary>
        public virtual string GetSubstituteProducts(string sitemCode, bool useXmlDesign)
        {
            string ProductID = new InputValidator("SubstituteProducts")
                                    .ValidateString("ItemCode", sitemCode);
            return InterpriseHelper.ShowInventorySubstituteOptions(sitemCode, 100, true, string.Empty, ThisCustomer, this.XmlPackageHelperTemplate);
        }

        public virtual string DocumentLink(string sDocumentID, String sSEName, String sIncludeATag, string sTagInnerText)
        {
            // (!DocumentLink DocumentID="N" SEName="xxx" IncludeATag="true/false"!)
            InputValidator IV = new InputValidator("DocumentLink");
            String DocumentID = IV.ValidateString("DocumentID", sDocumentID);
            String SEName = IV.ValidateString("SEName", sSEName);
            bool IncludeATag = IV.ValidateBool("IncludeATag", sIncludeATag);
            String TagInnerText = IV.ValidateString("TagInnerText", sTagInnerText);
            string result = String.Empty;
            result = SE.MakeObjectLink("Document", DocumentID, SEName);
            if (IncludeATag)
            {
                result = "<a href=\"" + result + "\">" + TagInnerText + "</a>";
            }
            return result;
        }

        public virtual string ProductandCategoryLink(string sProductID, String sSEName, string sCategoryID, String sIncludeATag, string sTagInnerText)
        {
            // (!ProductAndCategoryLink ProductID="N" CategoryID="M" SEName="xxx" IncludeATag="true/false"!)

            InputValidator IV = new InputValidator("ProductandCategoryLink");
            String ProductID = IV.ValidateString("ProductID", sProductID);
            String CategoryID = IV.ValidateString("CategoryID", sCategoryID);
            String SEName = IV.ValidateString("SEName", sSEName);
            bool IncludeATag = IV.ValidateBool("IncludeATag", sIncludeATag);
            String TagInnerText = IV.ValidateString("TagInnerText", sTagInnerText);
            string result = String.Empty;
            result = SE.MakeProductAndCategoryLink(ProductID, CategoryID, SEName);
            if (IncludeATag)
            {
                result = "<a href=\"" + result + "\">" + TagInnerText + "</a>";
            }
            return result;
        }

        public virtual string ProductandSectionLink(string sProductID, String sSEName, string sDepartmentID, String sIncludeATag, string sTagInnerText)
        {
            // (!ProductAndSectionLink ProductID="N" DepartmentID="M" SEName="xxx" IncludeATag="true/false"!)
            InputValidator IV = new InputValidator("ProductandSectionLink");
            String DepartmentID = IV.ValidateString("SectionID", sDepartmentID);
            String ProductID = IV.ValidateString("ProductID", sProductID);
            String SEName = IV.ValidateString("SEName", sSEName);
            bool IncludeATag = IV.ValidateBool("IncludeATag", sIncludeATag);
            String TagInnerText = IV.ValidateString("TagInnerText", sTagInnerText);
            string result = String.Empty;
            result = SE.MakeProductAndSectionLink(ProductID, DepartmentID, SEName);
            if (IncludeATag)
            {
                result = "<a href=\"" + result + "\">" + TagInnerText + "</a>";
            }
            return result;
        }

        public virtual string ProductandManufacturerLink(string sProductID, String sSEName, string sManufacturerID, String sIncludeATag, string sTagInnerText)
        {
            // (!ProductAndManufacturerLink ProductID="N" ManufacturerID="M" SEName="xxx" IncludeATag="true/false"!)
            InputValidator IV = new InputValidator("ProductandManufacturerLink");
            String ProductID = IV.ValidateString("ProductID", sProductID);
            String ManufacturerID = IV.ValidateString("ManufacturerID", sManufacturerID);
            String SEName = IV.ValidateString("SEName", sSEName);
            bool IncludeATag = IV.ValidateBool("IncludeATag", sIncludeATag);
            String TagInnerText = IV.ValidateString("TagInnerText", sTagInnerText);
            string result = String.Empty;
            result = SE.MakeProductAndEntityLink("Manufacturer", ProductID, ManufacturerID, SEName);
            if (IncludeATag)
            {
                result = "<a href=\"" + result + "\">" + TagInnerText + "</a>";
            }
            return result;
        }

        public virtual string ProductProperName(string sProductID, string sVariantID)
        {
            InputValidator IV = new InputValidator("ProductProperName");
            String ProductID = IV.ValidateString("ProductID", sProductID);
            String VariantID = IV.ValidateString("VariantID", sVariantID);
            string result = String.Empty;
            result = AppLogic.MakeProperProductName(ProductID, VariantID, ThisCustomer.LocaleSetting);
            return result;
        }

        public virtual string DocumentandLibraryLink(string sDocumentID, String sSEName, string sLibraryID, String sIncludeATag, string sTagInnerText)
        {
            // (!DocumentAndLibraryLink DocumentID="N" LibraryID="M" SEName="xxx" IncludeATag="true/false"!)
            InputValidator IV = new InputValidator("DocumentandLibraryLink");
            String DocumentID = IV.ValidateString("DocumentID", sDocumentID);
            String LibraryID = IV.ValidateString("LibraryID", sLibraryID);
            String SEName = IV.ValidateString("SEName", sSEName);
            bool IncludeATag = IV.ValidateBool("IncludeATag", sIncludeATag);
            String TagInnerText = IV.ValidateString("TagInnerText", sTagInnerText);
            string result = String.Empty;
            result = SE.MakeObjectAndEntityLink("Document", "Library", DocumentID, LibraryID, SEName);
            if (IncludeATag)
            {
                result = "<a href=\"" + result + "\">" + TagInnerText + "</a>";
            }
            return result;
        }

        public virtual string EntityLink(string sEntityID, string sSEName, string sEntityName, string sIncludeATag, string sTagInnerText)
        {
            // (!EntityLink EntityID="N" EntityName="xxx" SEName="xxx" IncludeATag="true/false"!)
            InputValidator IV = new InputValidator("EntityLink");
            String EntityID = IV.ValidateString("EntityID", sEntityID);
            String SEName = IV.ValidateString("SEName", sSEName);
            String EntityName = IV.ValidateString("EntityName", sEntityName);
            bool IncludeATag = IV.ValidateBool("IncludeATag", sIncludeATag);
            String TagInnerText = IV.ValidateString("TagInnerText", sTagInnerText);
            string result = String.Empty;
            result = SE.MakeEntityLink(EntityName, EntityID, SEName);
            if (IncludeATag)
            {
                result = "<a href=\"" + result + "\">" + TagInnerText + "</a>";
            }
            return result;
        }

        public virtual string ObjectLink(string sObjectID, String sSEName, String sObjectName, String sIncludeATag, string sTagInnerText)
        {
            // (!ObjectLink ObjectID="N" ObjectName="xxx" SEName="xxx" IncludeATag="true/false"!)
            InputValidator IV = new InputValidator("ObjectLink");
            String ObjectName = IV.ValidateString("ObjectName", sObjectName);
            String ObjectID = IV.ValidateString("ObjectID", sObjectID);
            String SEName = IV.ValidateString("SEName", sSEName);
            bool IncludeATag = IV.ValidateBool("IncludeATag", sIncludeATag);
            String TagInnerText = IV.ValidateString("TagInnerText", sTagInnerText);
            string result = String.Empty;
            result = SE.MakeObjectLink(ObjectName, ObjectID, SEName);
            if (IncludeATag)
            {
                result = "<a href=\"" + result + "\">" + TagInnerText + "</a>";
            }
            return result;
        }

        public virtual string ProductandEntityLink(String sProductID, String sSEName, String sEntityID, String sEntityName, String sIncludeATag, string sTagInnerText)
        {
            // (!ProductAndEntityLink ProductID="N" EntityID="M" EntityName="xxx" SEName="xxx" IncludeATag="true/false"!)
            InputValidator IV = new InputValidator("ProductandEntityLink");
            String ProductID = IV.ValidateString("ProductID", sProductID);
            String EntityID = IV.ValidateString("EntityID", sEntityID);
            String SEName = IV.ValidateString("SEName", sSEName);
            bool IncludeATag = IV.ValidateBool("IncludeATag", sIncludeATag);
            String TagInnerText = IV.ValidateString("TagInnerText", sTagInnerText);
            String EntityName = IV.ValidateString("EntityName", sEntityName);
            string result = String.Empty;
            result = SE.MakeProductAndEntityLink(EntityName, ProductID, EntityID, SEName);
            if (IncludeATag)
            {
                result = "<a href=\"" + result + "\">" + TagInnerText + "</a>";
            }
            return result;
        }

        public virtual string Topic(String sTopicName, String sTopicID)
        {
            InputValidator IV = new InputValidator("Topic");
            String TopicName = IV.ValidateString("TopicName", sTopicName);
            String TopicID = IV.ValidateString("TopicID", sTopicID);

            String LCL = ThisCustomer.LocaleSetting;
            string result = String.Empty;
            if (TopicID != String.Empty)
            {
                Topic t = new Topic(TopicID, LCL, ThisCustomer.SkinID);
                result = t.Contents;
            }

            if (TopicName.Length != 0)
            {
                Topic t = new Topic(TopicName, LCL, ThisCustomer.SkinID);
                result = t.Contents;
            }
            Parser p = new Parser(ThisCustomer.SkinID, ThisCustomer);
            result = p.ReplaceTokens(result);
            return result;
        }

        public virtual string Topic(String sTopicName)
        {
            var IV = new InputValidator("Topic");
            string topicName = IV.ValidateString("TopicName", sTopicName);
            string lcl = ThisCustomer.LocaleSetting;
            string result = String.Empty;

            if (topicName.Length != 0)
            {
                var t = new Topic(topicName, lcl, ThisCustomer.SkinID);
                result = t.Contents;

                var p = new Parser(ThisCustomer.SkinID, ThisCustomer);
                result = p.ReplaceTokens(result);
            }

            return result;
        }

        public virtual string AppConfig(String sAppConfigName)
        {
            InputValidator IV = new InputValidator("AppConfig");
            String AppConfigName = IV.ValidateString("AppConfigName", sAppConfigName);
            string result = String.Empty;
            if (AppConfigName.Length != 0)
            {
                result = AppLogic.AppConfig(AppConfigName);
            }
            return result;
        }
        public virtual string AppConfigBool(String sAppConfigName)
        {
            InputValidator IV = new InputValidator("AppConfigBool");
            String AppConfigName = IV.ValidateString("AppConfigName", sAppConfigName);
            return AppLogic.AppConfigBool(AppConfigName).ToString().ToLowerInvariant();
        }

        public bool EvalBool(string sEvalString)
        {
            InputValidator IV = new InputValidator("EvalBool");
            String EvalString = IV.ValidateString("EvalString", sEvalString);
            String tmp = EvalString;
            if ("TRUE".Equals(tmp, StringComparison.InvariantCultureIgnoreCase) ||
                "YES".Equals(tmp, StringComparison.InvariantCultureIgnoreCase) ||
                "1".Equals(tmp, StringComparison.InvariantCultureIgnoreCase))
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        public virtual string StringResource(String sStringResourceName)
        {
            InputValidator IV = new InputValidator("StringResource");
            String StringResourceName = IV.ValidateString("StringResourceName", sStringResourceName);
            if (AppLogic.AppConfigBool("ShowStringResourceKeys"))
            {
                return StringResourceName;
            }
            string result = String.Empty;
            if (StringResourceName.Length != 0)
            {
                result = AppLogic.GetString(StringResourceName, ThisCustomer.SkinID, ThisCustomer.LocaleSetting);
            }
            return result;
        }
        
        public virtual string StringResource(String sStringResourceName, String sLocaleSetting)
        {
            InputValidator IV = new InputValidator("StringResource");
            String StringResourceName = IV.ValidateString("StringResourceName", sStringResourceName);
            String LocaleSetting = IV.ValidateString("LocaleSetting", sLocaleSetting);
            if (AppLogic.AppConfigBool("ShowStringResourceKeys"))
            {
                return StringResourceName;
            }
            string result = String.Empty;
            if (StringResourceName.Length != 0)
            {
                result = AppLogic.GetString(StringResourceName, ThisCustomer.SkinID, LocaleSetting);
            }
            return result;
        }

        //uses a delimited list of params to format a StringResource that has format tags in it
        public virtual string StrFormatStringresource(string sStringResourceName, string sFormatParams, string sDelimiter)
        {
            InputValidator IV = new InputValidator("StrFormatStringresource");
            String StringResourceName = IV.ValidateString("StringResourceName", sStringResourceName);
            String FormatParams = IV.ValidateString("FormatParams", sFormatParams);
            String Delimiter = IV.ValidateString("Delimiter", sDelimiter);
            char[] delim = Delimiter.ToCharArray();
            string[] rParams = FormatParams.Split(delim);
            return String.Format(StringResource(StringResourceName), rParams);
        }

        public virtual string StringResourceTextOnly(String sStringResourceName)
        {
            InputValidator IV = new InputValidator("StringResource");
            String StringResourceName = IV.ValidateString("StringResourceName", sStringResourceName);
            if (AppLogic.AppConfigBool("ShowStringResourceKeys"))
            {
                return StringResourceName;
            }
            string result = String.Empty;
            if (StringResourceName.Length != 0)
            {
                result = AppLogic.GetString(StringResourceName, ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true);
            }
            return result;
        }

        //uses a delimited list of params to format a StringResource that has format tags in it
        public virtual string StrFormatStringresourceTextOnly(string sStringResourceName, string sFormatParams, string sDelimiter)
        {
            InputValidator IV = new InputValidator("StrFormatStringresource");
            String StringResourceName = IV.ValidateString("StringResourceName", sStringResourceName);
            String FormatParams = IV.ValidateString("FormatParams", sFormatParams);
            String Delimiter = IV.ValidateString("Delimiter", sDelimiter);
            char[] delim = Delimiter.ToCharArray();
            string[] rParams = FormatParams.Split(delim);
            return String.Format(StringResourceTextOnly(StringResourceName), rParams);
        }

        public virtual string SearchBox()
        {
            return AppLogic.GetSearchBox(ThisCustomer.SkinID, ThisCustomer.LocaleSetting);
        }
        public virtual string HelpBox()
        {
            string result = String.Empty;
            result = AppLogic.GetHelpBox(ThisCustomer.SkinID, true, ThisCustomer.LocaleSetting, null);
            return result;
        }

        public virtual string ShowAddToCartForm(int counter, String ProductID, String VariantID, bool ColorChangeProductImage, string FreeStockString)
        {
            decimal freeStock = decimal.Zero;
            decimal.TryParse(FreeStockString, out freeStock);
            string result = String.Empty;

            if (ProductID != String.Empty && VariantID != String.Empty)
            {
                return string.Empty;
            }
            else
            {
                result = String.Empty;
            }
            return result;
        }

        public virtual string AddtoCartForm(String ProductID, String VariantID, bool ColorChangeProductImage, bool ShowWishListButton, bool ShowGiftRegistryButtons)
        {
            throw new InvalidOperationException("Use ShowAddToCartForm instead!!!");
        }
        public virtual string AddtoCartForm(String ProductID, String VariantID, bool ColorChangeProductImage, bool ShowWishListButton, bool ShowGiftRegistryButtons, bool ForPack)
        {
            throw new InvalidOperationException("Use ShowAddToCartForm instead!!!");
        }

        public virtual string LookupEntityImage(String sID, String sEntityName, String sDesiredSize, String sIncludeATag)
        {
            InputValidator IV = new InputValidator("LookupEntityImage");
            String ID = IV.ValidateString("ID", sID);
            String EntityName = IV.ValidateString("EntityName", sEntityName);
            String DesiredSize = IV.ValidateString("DesiredSize", sDesiredSize);
            bool IncludeATag = IV.ValidateBool("IncludeATag", sIncludeATag);
            string result = String.Empty;
            if ("DOCUMENT".Equals(EntityName, StringComparison.InvariantCultureIgnoreCase))
            {
                result = String.Empty;
            }
            else
            {
                // a category, section, or manufacturer, etc...
                result = AppLogic.LookupImage(EntityName, ID, DesiredSize, ThisCustomer.SkinID, ThisCustomer.LocaleSetting);
                result = "<img border=\"0\" id=\"EntityPic" + ID.ToString() + "\" style=\"cursor:hand;cursor:pointer;\" src=\"" + result + "\" data-contentEntityType=\""
                    + EntityName + "\" data-contentCounter='" + ID + "' data-contentKey=\"" + ID + "\" class=\"content\" data-contentType=\"image\"" + ">";
            }
            return result;
        }

        public virtual string MobileLookupEntityImage(String sID, String sEntityName, String sDesiredSize, String sIncludeATag)
        {
            InputValidator IV = new InputValidator("LookupEntityImage");
            String ID = IV.ValidateString("ID", sID);
            String EntityName = IV.ValidateString("EntityName", sEntityName);
            String DesiredSize = IV.ValidateString("DesiredSize", sDesiredSize);
            bool IncludeATag = IV.ValidateBool("IncludeATag", sIncludeATag);
            string result = String.Empty;
            if ("DOCUMENT".Equals(EntityName, StringComparison.InvariantCultureIgnoreCase))
            {
                result = String.Empty;
            }
            else
            {
                return AppLogic.LookupImage(EntityName, ID, DesiredSize, ThisCustomer.SkinID, ThisCustomer.LocaleSetting);
            }
            return result;
        }

        public virtual string ImageUrl(String sID, String sEntityOrObjectName, String sDesiredSize, String sFullUrl)
        {
            InputValidator IV = new InputValidator("ImageUrl");
            String ID = IV.ValidateString("ID", sID);
            String EntityOrObjectName = IV.ValidateString("EntityOrObjectName", sEntityOrObjectName);
            bool FullUrl = IV.ValidateBool("FullUrl", sFullUrl);
            String DesiredSize = IV.ValidateString("DesiredSize", sDesiredSize);
            string result = String.Empty;
            string ImgPath = String.Empty;
            string sURL = CommonLogic.IIF(FullUrl, AppLogic.GetStoreHTTPLocation(false), "");
            sURL = sURL.Replace(AppLogic.AppConfig("AdminDir") + "/", "");
            if (sURL.EndsWith("/")) sURL = sURL.Substring(0, sURL.Length - 1);
            ImgPath = AppLogic.LookupImage(EntityOrObjectName, ID, DesiredSize, ThisCustomer.SkinID, ThisCustomer.LocaleSetting).Replace("..", "");
            result = sURL + CommonLogic.IIF(ImgPath.StartsWith("/"), "", "/") + ImgPath;
            return result;
        }

        public virtual string ProductImageUrl(String ProductID, String ImageFileNameOverride, String SKU, String DesiredSize, bool FullUrl)
        {
            string result = String.Empty;
            string ImgPath = String.Empty;
            string sURL = CommonLogic.IIF(FullUrl, AppLogic.GetStoreHTTPLocation(false), "");
            sURL = sURL.Replace(AppLogic.AppConfig("AdminDir") + "/", "");
            if (sURL.EndsWith("/")) sURL = sURL.Substring(0, sURL.Length - 1);

            if (AppLogic.AppConfigBool("Watermark.Enabled"))
            {
                ImgPath = String.Format("watermark.axd?counter={0}&size={1}", ProductID, DesiredSize.ToLower());
            }
            else
            {
                ImgPath = AppLogic.LookupImage("Product", ProductID, ImageFileNameOverride, SKU, DesiredSize, ThisCustomer.SkinID, ThisCustomer.LocaleSetting).Replace("..", "");
            }
            result = sURL + CommonLogic.IIF(ImgPath.StartsWith("/"), "", "/") + ImgPath;
            return result;
        }

        public bool Owns(String sProductID)
        {
            InputValidator IV = new InputValidator("Owns");
            String ProductID = IV.ValidateString("ProductID", sProductID);
            return AppLogic.Owns(ProductID, ThisCustomer.CustomerID);
        }

        public bool Owns(String sProductID, String sCustomerID)
        {
            InputValidator IV = new InputValidator("Owns");
            String ProductID = IV.ValidateString("ProductID", sProductID);
            String CustomerID = IV.ValidateString("CustomerID", sCustomerID);
            return AppLogic.Owns(ProductID, CustomerID);
        }

        public virtual string ProductNavLink(string productID, string direction)
        {
            if (AppLogic.AppConfigBool("HideProductNextPrevLinks")) return string.Empty;

            string SEName = string.Empty;
            string entityID = AppLogic.ReadCookie("LastViewedEntityInstanceID");
            string entityName = AppLogic.ReadCookie("LastViewedEntityName");
            string itemid = AppLogic.GetProductSequence(direction, productID, entityID, entityName, 0, false, true, true, out SEName);

            var xml = new XElement(DomainConstants.XML_ROOT_NAME);
            xml.Add(new XElement(DomainConstants.XML_SECTION_TYPE, XMLSectionType.DISPLAY_NAV_LINK));
            xml.Add(new XElement("ITEMCODE_CURRENT", AppLogic.GetItemCodeByCounter(Convert.ToInt32(productID))));

            if (direction == "previous") xml.Add(new XElement("ITEMCODE_PREV", AppLogic.GetItemCodeByCounter(Convert.ToInt32(itemid))));
            if (direction == "next") xml.Add(new XElement("ITEMCODE_NEXT", AppLogic.GetItemCodeByCounter(Convert.ToInt32(itemid))));

            var xmlpackage = new XmlPackage2(this.XmlPackageHelperTemplate, xml);
            return xmlpackage.TransformString();
        }

        public virtual string ProductNavLinks(string sProductID, string sEntityID, string sEntityName, string sEntitySEName, string sSortByLooks, string sUseGraphics, string sIncludeUpLink)
        {
            if (this.IsUsingHelperTemplate)
            {
                return ProductNavLinks(sProductID, sEntityID, sEntityName, sEntitySEName, sSortByLooks, sUseGraphics, sIncludeUpLink, true);
            }

            InputValidator IV = new InputValidator("ProductNavLinks");
            String ProductID = IV.ValidateString("ProductID", sProductID);
            String EntityID = IV.ValidateString("EntityID", sEntityID);
            String EntityName = IV.ValidateString("EntityName", sEntityName);
            String EntitySEName = IV.ValidateString("EntitySEName", sEntitySEName);
            bool SortByLooks = IV.ValidateBool("SortByLooks", sSortByLooks);
            bool UseGraphics = IV.ValidateBool("UseGraphics", sUseGraphics);
            bool IncludeUpLink = IV.ValidateBool("IncludeUpLink", sIncludeUpLink);
            string result = String.Empty;
            string SEName = String.Empty;
            StringBuilder tmpS = new StringBuilder("");
            if (EntityName.Trim() == "")
            {
                EntityName = "CATEGORY";
            }
            if (!AppLogic.AppConfigBool("HideProductNextPrevLinks"))
            {
                int NumProducts = 0;
                NumProducts = AppLogic.LookupHelper(EntityName).GetNumEntityObjects(EntityID, true, true);
                if (NumProducts > 1)
                {
                    string PreviousProductID = AppLogic.GetProductSequence("previous", ProductID, EntityID, EntityName, 0, SortByLooks, true, true, out SEName);
                    if (PreviousProductID.TryParseInt().Value > 0)
                    {
                        if (UseGraphics)
                        {
                            tmpS.Append("<a class=\"ProductNavLink\" href=\"" + SE.MakeProductAndEntityLink(EntityName, PreviousProductID, EntityID, SEName) + "\"><img src=\"" + AppLogic.LocateImageURL("skins/skin_" + ThisCustomer.SkinID.ToString() + "/images/previous.gif", ThisCustomer.LocaleSetting) + "\" border=\"0\"></a>&nbsp;&nbsp;");
                        }
                        else
                        {
                            tmpS.Append("<a class=\"ProductNavLink\" href=\"" + SE.MakeProductAndEntityLink(EntityName, PreviousProductID, EntityID, SEName) + "\">" + AppLogic.GetString("showproduct.aspx.4", ThisCustomer.SkinID, ThisCustomer.LocaleSetting) + "</a>&nbsp;|&nbsp;");
                        }
                    }
                }
                if (IncludeUpLink)
                {
                    if (UseGraphics)
                    {
                        tmpS.Append("<a class=\"ProductNavLink\" href=\"" + SE.MakeEntityLink(EntityName, EntityID, EntitySEName) + "\"><img src=\"" + AppLogic.LocateImageURL("skins/skin_" + ThisCustomer.SkinID.ToString() + "/images/up.gif", ThisCustomer.LocaleSetting) + "\" border=\"0\"></a>");
                    }
                    else
                    {
                        tmpS.Append("<a class=\"ProductNavLink\" href=\"" + SE.MakeEntityLink(EntityName, EntityID, EntitySEName) + "\">" + AppLogic.GetString("showproduct.aspx.5", ThisCustomer.SkinID, ThisCustomer.LocaleSetting) + "</a>");
                    }
                }
                if (NumProducts > 1)
                {
                    string NextProductID = AppLogic.GetProductSequence("next", ProductID, EntityID, EntityName, 0, SortByLooks, true, true, out SEName);
                    if (NextProductID.TryParseInt().Value > 0)
                    {
                        if (UseGraphics)
                        {
                            tmpS.Append("&nbsp;&nbsp;<a class=\"ProductNavLink\" href=\"" + SE.MakeProductAndEntityLink(EntityName, NextProductID, EntityID, SEName) + "\"><img src=\"" + AppLogic.LocateImageURL("skins/skin_" + ThisCustomer.SkinID.ToString() + "/images/next.gif", ThisCustomer.LocaleSetting) + "\" border=\"0\"></a>&nbsp;");
                        }
                        else
                        {
                            tmpS.Append("&nbsp;|&nbsp;<a class=\"ProductNavLink\" href=\"" + SE.MakeProductAndEntityLink(EntityName, NextProductID, EntityID, SEName) + "\">" + AppLogic.GetString("showproduct.aspx.6", ThisCustomer.SkinID, ThisCustomer.LocaleSetting) + "</a>&nbsp;");
                        }
                    }
                }
                result = tmpS.ToString();
            }
            return result;
        }

        public virtual string ProductNavLinks(string sProductID, string sEntityID, string sEntityName, string sEntitySEName, string sSortByLooks, string sUseGraphics, string sIncludeUpLink, bool useXmlDesign)
        {
            var IV = new InputValidator("ProductNavLinks");
            string ProductID = IV.ValidateString("ProductID", sProductID);
            string EntityID = IV.ValidateString("EntityID", sEntityID);
            string EntityName = IV.ValidateString("EntityName", sEntityName);
            string EntitySEName = IV.ValidateString("EntitySEName", sEntitySEName);
            bool SortByLooks = IV.ValidateBool("SortByLooks", sSortByLooks);
            bool UseGraphics = IV.ValidateBool("UseGraphics", sUseGraphics);
            bool IncludeUpLink = IV.ValidateBool("IncludeUpLink", sIncludeUpLink);
            string result = string.Empty;
            string SEName = string.Empty;
            var tmpS = new StringBuilder("");
            if (EntityName.Trim() == "")
            {
                EntityName = "CATEGORY";
            }

            var xml = new XElement(DomainConstants.XML_ROOT_NAME);
            xml.Add(new XElement(DomainConstants.XML_SECTION_TYPE, XMLSectionType.DISPLAY_NAV_LINKS));
            xml.Add(new XElement("USE_GRAPHICS", UseGraphics.ToString().ToLowerInvariant()));
            xml.Add(new XElement("HIDEPRODUCTNEXTPREVLINKS", AppLogic.AppConfigBool("HideProductNextPrevLinks").ToString().ToLowerInvariant()));
            xml.Add(new XElement("INCLUDEUPLINK", IncludeUpLink.ToString().ToLowerInvariant()));
            xml.Add(new XElement("SKIN_ID", ThisCustomer.SkinID.ToString()));

            //Node: This code was added due to invalid checking if the product is not belong to any department or category. It produced invalid url
            //If EntitySEName is empty hide the up arrow from the helper.product.xml.config
            xml.Add(new XElement("ENTITY_SENAME", EntitySEName));

            if (AppLogic.AppConfigBool("HideProductNextPrevLinks")) return string.Empty;

            int NumProducts = 0;
            NumProducts = AppLogic.LookupHelper(EntityName).GetNumEntityObjects(EntityID, true, true);
            if (NumProducts > 1)
            {
                string PreviousProductID = AppLogic.GetProductSequence("previous", ProductID, EntityID, EntityName, 0, SortByLooks, true, true, out SEName);
                if (PreviousProductID.TryParseInt().Value > 0)
                {
                    if (!UseGraphics)
                    {
                        xml.Add(new XElement("PREV_NO_IMAGE_TEXT", AppLogic.GetString("showproduct.aspx.4", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true)));
                    }
                    xml.Add(new XElement("PREV_HREF", SE.MakeProductAndEntityLink(EntityName, PreviousProductID, EntityID, SEName)));
                }
            }

            if (IncludeUpLink)
            {
                if (!UseGraphics)
                {
                    xml.Add(new XElement("UP_NO_IMAGE_TEXT", AppLogic.GetString("showproduct.aspx.5", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true)));
                }
                xml.Add(new XElement("UP_HREF", SE.MakeEntityLink(EntityName, EntityID, EntitySEName)));
            }

            if (NumProducts > 1)
            {
                string NextProductID = AppLogic.GetProductSequence("next", ProductID, EntityID, EntityName, 0, SortByLooks, true, true, out SEName);
                if (NextProductID.TryParseInt().Value > 0)
                {
                    if (!UseGraphics)
                    {
                        xml.Add(new XElement("NEXT_NO_IMAGE_TEXT", AppLogic.GetString("showproduct.aspx.6", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true)));
                    }
                    xml.Add(new XElement("NEXT_HREF", SE.MakeProductAndEntityLink(EntityName, NextProductID, EntityID, SEName)));
                }
            }

            var xmlpackage = new XmlPackage2(this.XmlPackageHelperTemplate, xml);
            return xmlpackage.TransformString();
        }

        //Obsolete Code

        //public virtual string EmailProductToFriend(string ProductID, string CategoryID)
        //{
        //    if (this.IsUsingHelperTemplate && CurrentContext.IsRequestingFromMobileBrowser())
        //    {
        //        return EmailProductToFriend(ProductID, CategoryID, true);
        //    }

        //    string result = String.Empty;
        //    if (AppLogic.AppConfigBool("ShowEMailProductToFriend"))
        //    {
        //        String S1 = String.Empty;
        //        result = "<br/><small><img src=\"" + AppLogic.LocateImageURL("skins/skin_" + ThisCustomer.SkinID.ToString() +
        //            "/images/mailicon.gif") + "\" border=\"0\" align=\"absmiddle\">&nbsp;<a href=\"emailproduct.aspx?productId=" +
        //            ProductID.ToString() + "&categoryid=" + CategoryID.ToString() + "\">" +
        //            AppLogic.GetString("showproduct.aspx.12", ThisCustomer.SkinID, ThisCustomer.LocaleSetting) + "</a></small><br/><br/>";
        //    }
        //    return result;
        //}

        //public virtual string EmailProductToFriend(string ProductID, string CategoryID, bool useXmlDesign)
        //{
        //    if (!AppLogic.AppConfigBool("ShowEMailProductToFriend")) return string.Empty;

        //    string imageUrl = AppLogic.LocateImageURL("skins/skin_" + ThisCustomer.SkinID.ToString() + "/images/mailicon.gif");
        //    var rootElement = new XElement(DomainConstants.XML_ROOT_NAME);
        //    rootElement.Add(new XElement(DomainConstants.XML_SECTION_TYPE, XMLSectionType.DISPLAY_EMAILPRODUCTTOFRIEND.ToString()));
        //    rootElement.Add(new XElement("EMAILICON_URL", imageUrl));
        //    rootElement.Add(new XElement("PRODUCT_ID", ProductID.ToString()));
        //    rootElement.Add(new XElement("CATEGORY_ID", CategoryID.ToString()));
        //    rootElement.Add(new XElement("LINK_TEXT", AppLogic.GetString("showproduct.aspx.12", ThisCustomer.SkinID, ThisCustomer.LocaleSetting)));

        //    string retval = string.Empty;
        //    using (var pagckage = new XmlPackage2(this.XmlPackageHelperTemplate, rootElement))
        //    {
        //        retval = pagckage.TransformString();
        //    }

        //    return retval;
        //}

        public virtual string ProductDescriptionFile(String sProductID, String sIncludeBRBefore)
        {
            InputValidator IV = new InputValidator("ProductDescriptionFile");
            string ProductID = IV.ValidateString("sProductID", sProductID);
            bool IncludeBRBefore = IV.ValidateBool("sIncludeBRBefore", sIncludeBRBefore);
            string result = String.Empty;
            String FileDescription = new ProductDescriptionFile(ProductID, ThisCustomer.LocaleSetting, ThisCustomer.SkinID).Contents;
            if (IncludeBRBefore && FileDescription.Length != 0)
            {
                result = "<br />" + FileDescription;
            }
            else
            {
                result = FileDescription;
            }
            return result;

        }

        public virtual string ProductRatings(String sItemCode)
        {
            String itemCode = string.Empty;
            if (AppLogic.AppConfigBool("Ratings.Enabled"))
            {
                InputValidator IV = new InputValidator("ProductRatings");
                itemCode = IV.ValidateString("ItemCode", sItemCode);

                try
                {
                    RatingCollection ratings = RatingCollection.ForItem(itemCode);
                    return ratings.Display(Customer.Current);
                }
                catch (Exception ex)
                {
                    return HttpUtility.HtmlEncode(ex.Message);
                }
            }
            return string.Empty;
        }

        public virtual string ProductEntityList(string sProductID, string sEntityName)
        {
            if (this.IsUsingHelperTemplate && CurrentContext.IsRequestingFromMobileMode(ThisCustomer))
            {
                return ProductEntityList(sProductID, sEntityName, true);
            }
            var IV = new InputValidator("ProductEntityList");
            string ProductID = IV.ValidateString("ProductID", sProductID);
            string EntityName = IV.ValidateString("EntityName", sEntityName);
            var results = new StringBuilder("");

            var eh = AppLogic.LookupHelper(EntityName.ToLowerInvariant());
            string Entities = eh.GetObjectEntities(ProductID, false);
            if (Entities.Length != 0)
            {
                var EntityIDs = Entities.Split(',');
                bool firstEntity = true;
                foreach (string s in EntityIDs)
                {
                    if (!firstEntity)
                    {
                        results.Append(", ");
                    }
                    results.Append("<a href=\"" + SE.MakeEntityLink(EntityName, Convert.ToString(Localization.ParseUSInt(s)), string.Empty) + "\">" + eh.GetEntityField(Convert.ToString(Localization.ParseUSInt(s)), "Description", ThisCustomer.LocaleSetting).Trim() + "</a>");
                    firstEntity = false;
                }
            }
            else
            {
                results.Append("");
            }
            return results.ToString();
        }

        /// <summary>
        /// This is used to automatically invoke the design from xmlpackage
        /// </summary>
        public virtual string ProductEntityList(string sProductID, string sEntityName, bool useXmlDesign)
        {
            var IV = new InputValidator("ProductEntityList");
            string ProductID = IV.ValidateString("ProductID", sProductID);
            string EntityName = IV.ValidateString("EntityName", sEntityName);

            string output = string.Empty;

            var eh = AppLogic.LookupHelper(EntityName.ToLowerInvariant());
            var m_TblMgr = eh.m_TblMgr;
            string Entities = eh.GetObjectEntities(ProductID, false);
            if (Entities.Length != 0)
            {
                var xml = new XElement(DomainConstants.XML_ROOT_NAME);
                xml.Add(new XElement(DomainConstants.XML_SECTION_TYPE, XMLSearchSectionType.DISPLAY_PRODUCTENTITYLIST.ToString()));
                var EntityIDs = Entities.Split(',');

                EntityIDs.ForEach(en =>
                {
                    var entityXml = new XElement("ENTITYXML");
                    entityXml.Add(new XElement("HREF", SE.MakeEntityLink(EntityName, Convert.ToString(Localization.ParseUSInt(en)), string.Empty)));
                    entityXml.Add(new XElement("NAME", eh.GetEntityField(Convert.ToString(Localization.ParseUSInt(en)), "Description", ThisCustomer.LocaleSetting).Trim()));
                    xml.Add(entityXml);
                });
                output = new XmlPackage2(this.XmlPackageHelperTemplate, xml).TransformString();
            }
            else
            {
                return output;
            }
            return output;
        }

        // uses the DisplaySpec if provided for output display
        // else uses DisplayLocale if provided
        // input string expected in SQL Locale format
        public virtual string FormatCurrency(string sCurrencyValue)
        {
            InputValidator IV = new InputValidator("FormatCurrency");
            String CurrencyValue = IV.ValidateString("CurrencyValue", sCurrencyValue);
            return FormatCurrencyHelper(Localization.ParseDBDecimal(CurrencyValue));
        }

        // uses the DisplaySpec if provided for output display
        // else uses DisplayLocale if provided
        // input string expected in SQL Locale format
        public virtual string FormatCurrency(string sCurrencyValue, String sTargetCurrency)
        {
            InputValidator IV = new InputValidator("FormatCurrency");
            String CurrencyValue = IV.ValidateString("CurrencyValue", sCurrencyValue);
            String TargetCurrency = IV.ValidateString("TargetCurrency", sTargetCurrency);
            return FormatCurrencyHelper(Localization.ParseDBDecimal(CurrencyValue), TargetCurrency);
        }

        // internal helper function only!
        protected virtual String FormatCurrencyHelper(decimal amt)
        {
            String TargetCurrency = Localization.GetPrimaryCurrency();
            if (ThisCustomer != null)
            {
                TargetCurrency = ThisCustomer.CurrencyCode;
            }
            return Localization.CurrencyStringForDisplayWithExchangeRate(amt, TargetCurrency);
        }

        // internal helper function only!
        protected virtual String FormatCurrencyHelper(decimal amt, String TargetCurrency)
        {
            if (TargetCurrency == null || TargetCurrency.Length == 0)
            {
                if (ThisCustomer != null)
                {
                    TargetCurrency = ThisCustomer.CurrencyCode;
                }
                else
                {
                    TargetCurrency = Localization.GetPrimaryCurrency();
                }
            }

            return InterpriseHelper.FormatCurrencyForCustomer(amt, TargetCurrency);
        }

        public virtual string GetSpecialsBoxExpandedRandom(string sCategoryID, string sShowPics, string sIncludeFrame, string sTeaser)
        {
            if (this.IsUsingHelperTemplate && CurrentContext.IsRequestingFromMobileMode(ThisCustomer))
            {
                GetSpecialsBoxExpandedRandom(sCategoryID, sShowPics, sIncludeFrame, sTeaser, true);
            }

            var IV = new InputValidator("GetSpecialsBoxExpandedRandom");
            string CategoryID = IV.ValidateString("CategoryID", sCategoryID);
            bool ShowPics = IV.ValidateBool("ShowPics", sShowPics);
            bool IncludeFrame = IV.ValidateBool("IncludeFrame", sIncludeFrame);
            string Teaser = IV.ValidateString("Teaser", sTeaser);
            return AppLogic.GetSpecialsBoxExpandedRandom(CategoryID, ShowPics, IncludeFrame, Teaser, ThisCustomer.SkinID, ThisCustomer.LocaleSetting, ThisCustomer);
        }

        /// <summary>
        /// This is used to automatically invoke the design from xmlpackage
        /// </summary>
        public virtual string GetSpecialsBoxExpandedRandom(string sCategoryID, string sShowPics, string sIncludeFrame, string sTeaser, bool useXmlDesign)
        {
            var IV = new InputValidator("GetSpecialsBoxExpandedRandom");
            string CategoryID = IV.ValidateString("CategoryID", sCategoryID);
            bool ShowPics = IV.ValidateBool("ShowPics", sShowPics);
            bool IncludeFrame = IV.ValidateBool("IncludeFrame", sIncludeFrame);
            string Teaser = IV.ValidateString("Teaser", sTeaser);
            return AppLogic.GetSpecialsBoxExpandedRandom(CategoryID, ShowPics, IncludeFrame, Teaser, ThisCustomer.SkinID, ThisCustomer.LocaleSetting, ThisCustomer, this.XmlPackageHelperTemplate);
        }

        public virtual string GetSpecialsBoxExpanded(string sCategoryID, string sShowNum, string sShowPics, string sIncludeFrame, string sTeaser)
        {
            if (this.IsUsingHelperTemplate && CurrentContext.IsRequestingFromMobileMode(ThisCustomer))
            {
                return GetSpecialsBoxExpanded(sCategoryID, sShowNum, sShowPics, sIncludeFrame, sTeaser, true);
            }

            var IV = new InputValidator("GetSpecialsBoxExpanded");
            string CategoryID = IV.ValidateString("CategoryID", sCategoryID);
            int ShowNum = IV.ValidateInt("ShowNum", sShowNum);
            bool ShowPics = IV.ValidateBool("ShowPics", sShowPics);
            bool IncludeFrame = IV.ValidateBool("IncludeFrame", sIncludeFrame);
            string Teaser = IV.ValidateString("Teaser", sTeaser);
            return AppLogic.GetSpecialsBoxExpanded(CategoryID, ShowNum, AppLogic.CachingOn, ShowPics, IncludeFrame, Teaser, ThisCustomer.SkinID, ThisCustomer.LocaleSetting, ThisCustomer);
        }

        public virtual string GetSpecialsBoxExpanded(string sCategoryID, string sShowNum, string sShowPics, string sIncludeFrame, string sTeaser, bool useSeparateXml)
        {
            var IV = new InputValidator("GetSpecialsBoxExpanded");
            string CategoryID = IV.ValidateString("CategoryID", sCategoryID);
            int ShowNum = IV.ValidateInt("ShowNum", sShowNum);
            bool ShowPics = IV.ValidateBool("ShowPics", sShowPics);
            bool IncludeFrame = IV.ValidateBool("IncludeFrame", sIncludeFrame);
            string Teaser = IV.ValidateString("Teaser", sTeaser);
            return AppLogic.GetSpecialsBoxExpanded(CategoryID, ShowNum, AppLogic.CachingOn, ShowPics, IncludeFrame, Teaser, ThisCustomer.SkinID, ThisCustomer.LocaleSetting, ThisCustomer, this.XmlPackageHelperTemplate);
        }

        public virtual string GetNewsBoxExpanded(String sShowCopy, String sShowNum, String sIncludeFrame, String sTeaser)
        {
            if (this.IsUsingHelperTemplate && CurrentContext.IsRequestingFromMobileMode(ThisCustomer))
            {
                return GetNewsBoxExpanded(sShowCopy, sShowNum, sIncludeFrame, sTeaser, true);
            }

            var IV = new InputValidator("GetNewsBoxExpanded");
            bool ShowCopy = IV.ValidateBool("ShowCopy", sShowCopy);
            int ShowNum = IV.ValidateInt("ShowNum", sShowNum);
            bool IncludeFrame = IV.ValidateBool("IncludeFrame", sIncludeFrame);
            string Teaser = IV.ValidateString("Teaser", sTeaser);
            string result = string.Empty;
            result = AppLogic.GetNewsBoxExpanded((CommonLogic.GetThisPageName(false).IndexOf("NEWS.ASPX", StringComparison.InvariantCultureIgnoreCase) == -1), ShowCopy, ShowNum, IncludeFrame, AppLogic.CachingOn, Teaser, ThisCustomer.SkinID, ThisCustomer.LocaleSetting);
            return result;
        }

        public virtual string GetNewsBoxExpanded(String sShowCopy, String sShowNum, String sIncludeFrame, String sTeaser, bool useXmlDesign)
        {
            var IV = new InputValidator("GetNewsBoxExpanded");
            bool ShowCopy = IV.ValidateBool("ShowCopy", sShowCopy);
            int ShowNum = IV.ValidateInt("ShowNum", sShowNum);
            bool IncludeFrame = IV.ValidateBool("IncludeFrame", sIncludeFrame);
            string Teaser = IV.ValidateString("Teaser", sTeaser);
            return AppLogic.GetNewsBoxExpanded((CommonLogic.GetThisPageName(false).IndexOf("NEWS.ASPX", StringComparison.InvariantCultureIgnoreCase) == -1), ShowCopy, ShowNum, IncludeFrame, AppLogic.CachingOn, Teaser, ThisCustomer.SkinID, ThisCustomer.LocaleSetting, this.XmlPackageHelperTemplate);
        }

        public virtual string UrlEncode(string sUrl)
        {
            InputValidator iv = new InputValidator("UrlEncode");
            string url = iv.ValidateString("Url", sUrl);

            return HttpUtility.UrlEncode(url);
        }

        public virtual string UrlDecode(string sUrl)
        {
            InputValidator iv = new InputValidator("UrlEncode");
            string url = iv.ValidateString("Url", sUrl);

            return HttpUtility.UrlDecode(url);
        }

        public virtual string ExtractBody(string html)
        {
            return CommonLogic.ExtractBody(html, true);
        }

        public virtual string Decode(string sHtmlContent)
        {
            InputValidator IV = new InputValidator("Decode");
            String HtmlContent = IV.ValidateString("HtmlContent", sHtmlContent);
            return HttpContext.Current.Server.HtmlDecode(HtmlContent);
        }

        public virtual string Encode(string sHtmlContent)
        {
            InputValidator IV = new InputValidator("Decode");
            String HtmlContent = IV.ValidateString("HtmlContent", sHtmlContent);
            return HttpContext.Current.Server.HtmlEncode(HtmlContent);
        }

        public virtual string Decrypt(string sEncryptedData)
        {
            InputValidator IV = new InputValidator("Decrypt");
            string EncryptedData = IV.ValidateString("EncryptedData", sEncryptedData);
            if (EncryptedData.Length == 0)
            {
                return "";
            }
            return Security.UnmungeString(EncryptedData);
        }

        public virtual string Decrypt(string sEncryptedData, String sSaltKey)
        {
            InputValidator IV = new InputValidator("Decrypt");
            string EncryptedData = IV.ValidateString("EncryptedData", sEncryptedData);
            string SaltKey = IV.ValidateString("SaltKey", sSaltKey);
            if (EncryptedData.Length == 0)
            {
                return "";
            }
            return Security.UnmungeString(EncryptedData, SaltKey);
        }

        public virtual string EncryptString(string sString2Encrypt)
        {
            InputValidator IV = new InputValidator("EncryptString");
            string String2Encrypt = IV.ValidateString("String2Encrypt", sString2Encrypt);
            return Security.MungeString(String2Encrypt);
        }

        public virtual string EncryptString(string sString2Encrypt, String sSaltKey)
        {
            InputValidator IV = new InputValidator("EncryptString");
            string String2Encrypt = IV.ValidateString("String2Encrypt", sString2Encrypt);
            string SaltKey = IV.ValidateString("SaltKey", sSaltKey);
            return Security.MungeString(String2Encrypt, SaltKey);
        }

        public virtual string XmlPackage(String sPackageName)
        {
            InputValidator IV = new InputValidator("XmlPackage");
            string PackageName = IV.ValidateString("PackageName", sPackageName);
            string result = String.Empty;
            if (PackageName.Length != 0)
            {
                if (!PackageName.EndsWith(".xml.config", StringComparison.InvariantCultureIgnoreCase))
                {
                    result = "Incorrect package name or package type";
                }
                else
                {
                    using (XmlPackage2 p = new XmlPackage2(PackageName, ThisCustomer))
                    {
                        // WARNING YOU COULD CAUSE ENDLESS RECURSION HERE! if your XmlPackage refers to itself in some direct, or INDIRECT! way!!
                        result = AppLogic.RunXmlPackage(p, new Parser(ThisCustomer.SkinID, ThisCustomer), ThisCustomer, ThisCustomer.SkinID, true, true);
                    }
                }
            }
            return result;
        }

        /// <summary>
        /// XmlPackage overload which allows a package to be loaded with specified runtime parameters.
        /// </summary>
        /// <param name="sPackageName">The name of the package to load. The package name must include the xml.config extension.</param>
        /// <param name="sAdditionalRuntimeParms">Querystring containing additional parameters that will be passed to the package as runtime values.</param>
        /// <returns>results of executing the specified package</returns>
        public virtual string XmlPackage(String sPackageName, String sAdditionalRuntimeParms)
        {
            InputValidator IV = new InputValidator("XmlPackage");
            string PackageName = IV.ValidateString("PackageName", sPackageName);
            string AdditionalRuntimeParms = IV.ValidateString("AdditionalRuntimeParms", sAdditionalRuntimeParms);
            string result = String.Empty;
            if (PackageName.Length != 0)
            {
                if (!PackageName.EndsWith(".xml.config", StringComparison.InvariantCultureIgnoreCase))
                {
                    result = "Incorrect package name or package type";
                }
                else
                {
                    List<XmlPackageParam> runtimeParams = AppLogic.MakeXmlPackageParamsFromString(AdditionalRuntimeParms);
                    using (XmlPackage2 p = new XmlPackage2(PackageName, ThisCustomer, ThisCustomer.SkinID, string.Empty, runtimeParams))
                    {
                        // WARNING YOU COULD CAUSE ENDLESS RECURSION HERE! if your XmlPackage refers to itself in some direct, or INDIRECT! way!!
                        result = AppLogic.RunXmlPackage(p, new Parser(ThisCustomer.SkinID, ThisCustomer), ThisCustomer, ThisCustomer.SkinID, true, true);
                    }
                }
            }
            return result;
        }

        public virtual string GetJSPopupRoutines()
        {
            return AppLogic.GetJSPopupRoutines();
        }

        public virtual decimal GetPriceForAdvanceSearch(String ItemCode)
        {
            decimal promotionalPrice = 0;
            decimal Price = 0;

            return Price = InterpriseHelper.GetSalesPrice(ThisCustomer.CustomerCode, ItemCode, ThisCustomer.CurrencyCode, decimal.One, ref promotionalPrice);
        }

        /// <summary>
        /// Get product price with optional currency symbol.
        /// </summary>
        /// <param name="itemCode">ItemCode</param>
        /// <param name="withCurrencySymbol">Determine if it returns with currency symbol</param>
        /// <returns>Product price</returns>
        public virtual string GetProductPrice(String itemCode, bool withCurrencySymbol)
        {
            decimal promotionalPrice = 0;
            decimal SalesPrice = 0;
            string Price = string.Empty;

            SalesPrice = InterpriseHelper.GetSalesPrice(ThisCustomer.CustomerCode, itemCode, ThisCustomer.CurrencyCode, decimal.One, ref promotionalPrice);
            if (promotionalPrice > decimal.Zero && promotionalPrice < SalesPrice)
            {
                if (withCurrencySymbol)
                {
                    Price = ThisCustomer.FormatBasedOnMyCurrency(promotionalPrice);
                }
                else
                {
                    Price = promotionalPrice.ToString();
                }
            }
            else
            {
                if (withCurrencySymbol)
                {
                    Price = ThisCustomer.FormatBasedOnMyCurrency(SalesPrice);
                }
                else
                {
                    Price = SalesPrice.ToString();
                }
            }
            return Price;
        }

        public virtual string EntityPageFilterOptions(string EntityName, string EntityID, string SectionFilterName, string CategoryFilterName, string ManufacturerFilterName, string ProductTypeFilterName)
        {
            int productFilter = 0;
            int.TryParse(ProductTypeFilterName, out productFilter);
            StringBuilder results = new StringBuilder("");
            string entName = string.Empty;

            bool m_AllowEntityPageFiltering = AppLogic.AppConfigBool("AllowEntityPageFiltering") && 
                                            ("CATEGORY".Equals(EntityName, StringComparison.InvariantCultureIgnoreCase) || 
                                            "DEPARTMENT".Equals(EntityName, StringComparison.InvariantCultureIgnoreCase) || 
                                            "MANUFACTURER".Equals(EntityName, StringComparison.InvariantCultureIgnoreCase));

            bool m_AllowManufacturerFiltering = AppLogic.AppConfigBool("AllowManufacturerFiltering");
            bool m_AllowProductTypeFiltering = AppLogic.AppConfigBool("AllowProductTypeFiltering");

            switch (EntityName.ToLower())
            {
                case "category": entName = CategoryFilterName;
                    break;
                case "department": entName = SectionFilterName;  
                    break;
                case "manufacturer":entName=ManufacturerFilterName;
                    break;
            }
            string postbackurl = SE.MakeEntityLink(EntityName, EntityID.ToString(), entName);
            if (m_AllowEntityPageFiltering)
            {
                results.Append("<div><form id=\"FilterForm\" name=\"FilterForm\" method=\"GET\" action=\"" + postbackurl + "\">\n");
                String QS = CommonLogic.ServerVariables("QUERY_STRING");
                results.Append("<table border=\"0\">");
                results.Append("<tr>\n");
                results.Append("<td colspan=\"2\">\n");
                results.Append("<a href=\"" + CommonLogic.GetThisPageName(false) + "?" + QS + CommonLogic.IIF(QS.Length == 0, "?", "&") + "resetfilters=true&entityname=" + EntityName + "&entityid=" + EntityID.ToString() + "\">RESET FILTERS</a>&nbsp;&nbsp;&nbsp;&nbsp;");
                results.Append("</td>\n");
                results.Append("</tr>\n");
                results.Append("<tr><td colspan=\"2\" height=\"1\"></td></tr>\n");
                
                if ("CATEGORY".Equals(EntityName, StringComparison.InvariantCultureIgnoreCase) ||
                    "MANUFACTURER".Equals(EntityName, StringComparison.InvariantCultureIgnoreCase))
                {
                    results.Append("<tr><td>\n");
                    results.Append(AppLogic.GetString("AppConfig.DepartmentPromptSingular", ThisCustomer.SkinID, ThisCustomer.LocaleSetting) + ": ");
                    results.Append("</td><td>\n");
                    results.Append("<select name=\"SectionFilterID\" onChange=\"document.FilterForm.submit()\" size=\"1\" style=\"font-size: 9px; width: 150px;\">\n");
                    results.Append("<OPTION VALUE=\"\" " + CommonLogic.IIF(SectionFilterName == String.Empty, " selected ", "") + ">" + AppLogic.GetString("searchadv.aspx.9", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true) + " " + AppLogic.GetString("AppConfig.DepartmentPromptPlural", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true) + "</option>\n");
                    EntityHelper SectionHelper = AppLogic.LookupHelper("Department");
                    String SecSel = SectionHelper.GetEntitySelectList("0", String.Empty, "0", ThisCustomer.LocaleSetting, false);
                    // mark current Section:
                    SecSel = SecSel.Replace("<option value=\"" + SectionFilterName.ToString() + "\">", "<option value=\"" + SectionFilterName.ToString() + "\" selected>");
                    results.Append(SecSel);
                    results.Append("</select>\n");
                    results.Append("</td></tr>\n");
                    results.Append("\n");
                }
                if ("DEPARTMENT".Equals(EntityName, StringComparison.InvariantCultureIgnoreCase) ||
                    "MANUFACTURER".Equals(EntityName, StringComparison.InvariantCultureIgnoreCase))
                {
                    results.Append("<tr><td>\n");
                    results.Append(AppLogic.GetString("AppConfig.CategoryPromptSingular", ThisCustomer.SkinID, ThisCustomer.LocaleSetting) + ": ");
                    results.Append("</td><td>\n");
                    results.Append("<select name=\"CategoryFilterID\" onChange=\"document.FilterForm.submit()\" size=\"1\" style=\"font-size: 9px; width: 150px;\">\n");
                    results.Append("<OPTION VALUE=\"\" " + CommonLogic.IIF(CategoryFilterName ==  String.Empty, " selected ", "") + ">" + AppLogic.GetString("searchadv.aspx.9", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true) + " " + AppLogic.GetString("AppConfig.CategoryPromptPlural", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true) + "</option>\n");
                    EntityHelper CategoryHelper = AppLogic.LookupHelper("Category");
                    String CatSel = CategoryHelper.GetEntitySelectList("0", String.Empty, "0", ThisCustomer.LocaleSetting, false);
                    // mark current Category:
                    CatSel = CatSel.Replace("<option value=\"" + CategoryFilterName.ToString() + "\">", "<option value=\"" + CategoryFilterName.ToString() + "\" selected>");
                    results.Append(CatSel);
                    results.Append("</select>\n");
                    results.Append("</td></tr>\n");
                }

                if ((m_AllowManufacturerFiltering) &&
                    false == "MANUFACTURER".Equals(EntityName, StringComparison.InvariantCultureIgnoreCase))
                {
                    results.Append("<tr><td>\n");
                    results.Append(AppLogic.GetString("AppConfig.ManufacturerPromptSingular", ThisCustomer.SkinID, ThisCustomer.LocaleSetting) + ": ");
                    results.Append("</td><td>\n");
                    results.Append("<select name=\"ManufacturerFilterID\" onChange=\"document.FilterForm.submit();\"  size=\"1\" style=\"font-size: 9px; width: 150px;\">\n");
                    results.Append("<OPTION VALUE=\"\" " + CommonLogic.IIF(ManufacturerFilterName == String.Empty, " selected ", "") + ">" + AppLogic.GetString("searchadv.aspx.9", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true) + " " + AppLogic.GetString("AppConfig.ManufacturerPromptPlural", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true) + "</option>\n");
                    EntityHelper ManufacturerHelper = AppLogic.LookupHelper("Manufacturer");
                    String MfgSel = ManufacturerHelper.GetEntitySelectList("0", String.Empty, "0", ThisCustomer.LocaleSetting, false);
                    // mark current Section:
                    MfgSel = MfgSel.Replace("<option value=\"" + ManufacturerFilterName.ToString() + "\">", "<option value=\"" + ManufacturerFilterName.ToString() + "\" selected>");
                    results.Append(MfgSel);
                    results.Append("</select>\n");
                    results.Append("</td></tr>\n");
                }

                if (m_AllowProductTypeFiltering)
                {
                    results.Append("<tr><td>\n");
                    results.Append(AppLogic.GetString("searchadv.aspx.7", ThisCustomer.SkinID, ThisCustomer.LocaleSetting) + " ");
                    results.Append("</td><td>\n");
                    results.Append("<select name=\"ProductTypeFilterID\" onChange=\"document.FilterForm.submit();\" size=\"1\" style=\"font-size: 9px; width: 150px;\">\n");
                    results.Append("<OPTION VALUE=\"0\" " + CommonLogic.IIF(ProductTypeFilterName == String.Empty, " selected ", "") + ">" + AppLogic.GetString("showcategory.aspx.2", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true) + "</option>\n");
                    
                    DataSet dsst = DB.GetDS("select Counter ProductTypeID, ItemType [Name] from InventoryItemType with (NOLOCK) where ItemType in ('Stock', 'Kit', 'Matrix Group', 'Non-Stock', 'Electronic Download', 'Service', 'Assembly') order by ItemType", AppLogic.CachingOn, DateTime.Now.AddMinutes(AppLogic.CacheDurationMinutes()));
                    foreach (DataRow row in dsst.Tables[0].Rows)
                    {
                        results.Append("<option value=\"" + DB.RowFieldInt(row, "ProductTypeID").ToString() + "\"");
                        if (DB.RowField(row, "ProductTypeID") == ProductTypeFilterName)
                        {
                            results.Append(" selected");
                        }
                        results.Append(">" + DB.RowFieldByLocale(row, "Name", ThisCustomer.LocaleSetting) + "</option>");
                    }
                    dsst.Dispose();
                    results.Append("</select>\n");
                    results.Append("</td></tr>\n");
                }
                results.Append("</table>\n");
                results.Append("</form>");
                results.Append("</div><br/>\n");
            }
            return results.ToString();
        }

        public virtual string EntityPageHeaderDescription(string sEntityName, String sEntityCode)
        {
            InputValidator IV = new InputValidator("EntityPageHeaderDescription");
            String EntityName = IV.ValidateString("EntityName", sEntityName);
            String EntityCode = IV.ValidateString("EntityCode", sEntityCode);

            StringBuilder results = new StringBuilder("");

            string EntityInstancePicture = AppLogic.LookupImage(EntityName, EntityCode, "medium", ThisCustomer.SkinID, ThisCustomer.LocaleSetting);
            EntityHelper m_EntityHelper = AppLogic.LookupHelper(EntityName);
            XmlNode n = m_EntityHelper.m_TblMgr.SetContext(EntityCode);

            string EntityInstanceDescription;

            if (m_EntityHelper.m_TblMgr.CurrentFieldByLocale(n, "WebDescription", ThisCustomer.LocaleSetting) != string.Empty)
            {
                EntityInstanceDescription = m_EntityHelper.m_TblMgr.CurrentFieldByLocale(n, "WebDescription", ThisCustomer.LocaleSetting);
            }
            else
            {
                EntityInstanceDescription = m_EntityHelper.m_TblMgr.CurrentFieldByLocale(n, "Description", ThisCustomer.LocaleSetting);
            }

            if (AppLogic.ReplaceImageURLFromAssetMgr)
            {
                EntityInstanceDescription = EntityInstanceDescription.Replace("../images", "images");
            }
            String FileDescription = new DescriptionFile(EntityName, EntityCode, ThisCustomer.LocaleSetting, ThisCustomer.SkinID).Contents;
            if (FileDescription.Length != 0)
            {
                EntityInstanceDescription += "<div align=\"left\">" + FileDescription + "</div>";
            }

            if (AppLogic.AppConfigBool("UseParserOnEntityDescriptions"))
            {
                Parser p = new Parser(ThisCustomer.SkinID, ThisCustomer);
                EntityInstanceDescription = p.ReplaceTokens(EntityInstanceDescription);
            }

            if (AppLogic.AppConfigBool("Force" + EntityName + "HeaderDisplay") || EntityInstanceDescription.Length != 0)
            {
                if (EntityInstanceDescription.Length != 0 && EntityInstancePicture.IndexOf("nopicture") == -1)
                {
                    results.Append("<img align=\"left\" src=\"" + EntityInstancePicture + "\" border=\"0\">");
                }
                results.Append("<span class=\"parent-category\">" + AppLogic.GetEntityName(EntityName, EntityCode, ThisCustomer.LocaleSetting) + "</span>");
                if (EntityInstanceDescription.Length != 0)
                {
                    results.Append("<span class=\"category-separator\">: </span> <span class=\"sub-category\">" + EntityInstanceDescription + "</span>");
                }
            }

            return results.ToString();
        }

        public virtual string GetEntityName(string sEntityName, String sEntityID)
        {
            InputValidator IV = new InputValidator("GetEntityName");
            String EntityName = IV.ValidateString("EntityName", sEntityName);
            String EntityID = IV.ValidateString("EntityID", sEntityID);
            return AppLogic.GetEntityName(EntityName, EntityID, ThisCustomer.LocaleSetting);
        }

        public virtual string GetMLValue(XPathNodeIterator MLContent)
        {
            InputValidator IV = new InputValidator("GetMLValue");
            return GetMLValue(MLContent, ThisCustomer.LocaleSetting);
        }

        public virtual string GetMLValue(XPathNodeIterator MLContent, string sLocale)
        {
            InputValidator IV = new InputValidator("GetMLValue");
            String Locale = IV.ValidateString("Locale", sLocale);
            if (Locale.Length == 0)
            {
                Locale = ThisCustomer.LocaleSetting;
            }
            return GetMLValue(MLContent, Locale, "FALSE");
        }

        public virtual string GetMLValue(XPathNodeIterator MLContent, string sLocale, String sXMLEncodeOutput)
        {
            InputValidator IV = new InputValidator("GetMLValue");
            String Locale = IV.ValidateString("Locale", sLocale);
            bool XMLEncodeOutput = IV.ValidateBool("XMLEncodeOutput", sXMLEncodeOutput);
            XPathNavigator xpn;
            MLContent.MoveNext();
            try
            {
                xpn = MLContent.Current;
            }
            catch
            {
                return "";
            }

            try
            {
                xpn.MoveToFirstChild();
                if (xpn.NodeType == XPathNodeType.Text)
                {
                    if (XMLEncodeOutput)
                    {
                        return xpn.OuterXml.Replace("&", "&amp;").Replace("<", "&lt;").Replace(">", "&gt;").Replace("'", "&apos;").Replace("\"", "&quot;").Trim();
                    }
                    else
                    {
                        return HttpContext.Current.Server.HtmlDecode(xpn.OuterXml).Trim();
                    }
                }
                else
                {
                    XPathNavigator n = xpn.SelectSingleNode("./locale[@name='" + Locale + "']");
                    if (n == null)
                    {
                        if (Locale != ThisCustomer.LocaleSetting)
                        {
                            n = xpn.SelectSingleNode("./locale[@name='" + ThisCustomer.LocaleSetting + "']");
                            if (n == null)
                            {
                                return "";
                            }
                            else
                            {
                                if (XMLEncodeOutput)
                                {
                                    return n.InnerXml.Replace("&", "&amp;").Replace("<", "&lt;").Replace(">", "&gt;").Replace("'", "&apos;").Replace("\"", "&quot;").Trim();
                                }
                                else
                                {
                                    return HttpContext.Current.Server.HtmlDecode(n.InnerXml).Trim();
                                }
                            }
                        }
                        return "";
                    }
                    else
                    {
                        if (XMLEncodeOutput)
                        {
                            return n.InnerXml.Replace("&", "&amp;").Replace("<", "&lt;").Replace(">", "&gt;").Replace("'", "&apos;").Replace("\"", "&quot;").Trim();
                        }
                        else
                        {
                            return HttpContext.Current.Server.HtmlDecode(n.InnerXml).Trim();
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                return "MLData Error: " + ex.Message;
            }

        }

        public virtual void LoadBatchProductImage(string sEntity, string sSize, string vposition, bool locateWithAttributes, XPathNodeIterator MLContent)
        {
            TempProductImageForEntityGrid = new List<ProductImage>();

            var codes = new List<string>();
            var ids = new List<string>();
            while (MLContent.MoveNext())
            {
                var currentNode = MLContent.Current;
                string itemCode = currentNode.SelectSingleNode("./ItemCode").InnerXml;
                string counter = currentNode.SelectSingleNode("./Counter").InnerXml;

                if (!itemCode.IsNullOrEmptyTrimmed() && !codes.Any(c => c == itemCode))
                {
                    codes.Add(itemCode);
                    ids = null;
                }
                else
                {
                    ids.Add(counter);
                    codes = null;
                }
                //string seAltext = currentNode.SelectSingleNode("./SEAltText").InnerXml;
            }

            if (codes.Count() > 0)
            {
                string languageCode = AppLogic.GetLanguageCode(ThisCustomer.LocaleSetting);
                TempProductImageForEntityGrid = ProductImage.LocateBulkDefaultImages(sEntity, sSize, languageCode, locateWithAttributes, codes, ids).ToArray();
            }
        }

        public virtual string Ellipses(string sContent, String sReturnLength, String sBreakBetweenWords)
        {
            InputValidator IV = new InputValidator("Ellipses");
            String Content = IV.ValidateString("Content", sContent);
            int ReturnLength = IV.ValidateInt("sReturnLength", sReturnLength);
            bool BreakBetweenWords = IV.ValidateBool("BreakBetweenWords", sBreakBetweenWords);
            return CommonLogic.Ellipses(Content, ReturnLength, BreakBetweenWords);
        }

        public virtual string ItemQuantityOption(string itemCode, string itemType, int counter)
        {
            // check if it's any of our supported for the meantime
            switch (itemType)
            {
                case Interprise.Framework.Base.Shared.Const.ITEM_TYPE_ELECTRONIC_DOWNLOAD:
                    DownloadableItem download = DownloadableItem.FindByItemCode(itemCode);
                    if (null == download)
                    {
                        return "<span>Not available for download</span>";
                    }
                    break;
                case Interprise.Framework.Base.Shared.Const.ITEM_TYPE_MATRIX_GROUP:
                case Interprise.Framework.Base.Shared.Const.ITEM_TYPE_MATRIX_ITEM:
                case Interprise.Framework.Base.Shared.Const.ITEM_TYPE_KIT:
                    return "<a href=\"" + InterpriseSuiteEcommerceCommon.InterpriseHelper.MakeItemLink(itemCode) + "\">More Info</a>";
            }

            StringBuilder results = new StringBuilder();

            // show the unit measure
            List<string> availableUnitMeasures = new List<string>();
            using (SqlConnection con = DB.NewSqlConnection())
            {
                con.Open();
                using (IDataReader reader = DB.GetRSFormat(con, "exec eCommerceGetProductUnitMeasureAvailability @CustomerCode = {0}, @ItemCode = {1}, @IncludeAllWarehouses = {2}, @Anon = {3}", DB.SQuote(ThisCustomer.CustomerCode), DB.SQuote(itemCode), AppLogic.AppConfigBool("ShowInventoryFromAllWarehouses"), ThisCustomer.IsNotRegistered))
                {
                    while (reader.Read())
                    {
                        availableUnitMeasures.Add(DB.RSField(reader, "UnitMeasureCode"));
                    }
                }
            }
            // NOTE :
            //  We should be guaranteed to have at least 1 unit measure
            //  and if it's 1 it should be the default...
            //  so we can safely assume that the first index is the Default unit measure
            if (availableUnitMeasures.Count > 1)
            {
                results.Append("<span >Unit Measure:</span>");
                // render as combobox
                results.AppendFormat("<select name=\"UnitMeasureCode_{0}\" id=\"UnitMeasureCode_{0}\" size=\"1\">", counter);
                results.AppendLine();

                for (int ctr = 0; ctr < availableUnitMeasures.Count; ctr++)
                {
                    string unitMeasureCode = availableUnitMeasures[ctr];
                    results.AppendFormat("<option value=\"{0}\" {1}>{0}</option>",
                        HttpUtility.HtmlEncode(unitMeasureCode),
                        (0 == ctr) ? "selected=\"selected\"" : string.Empty);
                }

                results.Append("</select>");
                results.AppendLine();
            }
            else
            {
                // register the unit measure control
                results.AppendFormat("<input type=\"hidden\" id=\"UnitMeasureCode_{0}\" name=\"UnitMeasureCode_{0}\" value=\"{1}\" />", counter, availableUnitMeasures[0]);
                results.AppendLine();
                // render as span
                results.AppendFormat("<span >Unit Measure: {0}</span>", HttpUtility.HtmlEncode(availableUnitMeasures[0]));
                results.AppendLine();

            }

            results.Append("&nbsp;");

            String Prompt = "Quantity: ";
            results.Append(Prompt);
            String FldName = counter.ToString();
            results.Append("<input name=\"Qty_" + FldName + "\" type=\"text\" size=\"3\" maxlength=\"3\">");

            return results.ToString();
        }

        public virtual bool IsCBNMode()
        {
            return AppLogic.IsCBNMode();
        }

        public virtual string ReplaceNewLineWithBR(string sContent)
        {
            InputValidator IV = new InputValidator("ReplaceNewLineWithBR");
            String Content = IV.ValidateString("Content", sContent);
            return Content.Replace("\n", "<br />");
        }

        public virtual string GetOrderReceiptCCNumber(string Last4, string CardType, string CardExpirationMonth, string CardExpirationYear, string ShowCCPWD, bool nocc)
        {
            StringBuilder results = new StringBuilder("");

            if (CardType.ToUpper(CultureInfo.InvariantCulture).StartsWith("PAYPAL"))
            {
                results.Append("<tr><td align=\"left\" width=\"20%\">" + AppLogic.GetString("order.cs.13", ThisCustomer.SkinID, ThisCustomer.LocaleSetting) + "</td><td colspan=\"3\" width=\"80%\" align=\"left\">Not Available</td></tr>");
                results.Append("<tr><td align=\"left\" width=\"20%\">" + AppLogic.GetString("order.cs.14", ThisCustomer.SkinID, ThisCustomer.LocaleSetting) + "</td><td colspan=\"3\" width=\"80%\" align=\"left\">Not Available</td></tr>");
            }
            else
            {
                results.Append("<tr><td align=\"left\" width=\"20%\">" + AppLogic.GetString("order.cs.13", ThisCustomer.SkinID, ThisCustomer.LocaleSetting) + "</td><td colspan=\"3\" width=\"80%\" align=\"left\">" + Last4 + "</td></tr>");
                results.Append("<tr><td align=\"left\" width=\"20%\">" + AppLogic.GetString("order.cs.14", ThisCustomer.SkinID, ThisCustomer.LocaleSetting) + "</td><td colspan=\"3\" width=\"80%\" align=\"left\">" + CardExpirationMonth + "/" + CardExpirationYear + "</td></tr>");
            }
            return results.ToString();
        }

        public virtual string DisplayOrderOptions(string OrderOptions, string ViewInLocaleSetting)
        {
            StringBuilder results = new StringBuilder("");
            if (OrderOptions.Length != 0)
            {
                results.Append("<div align=\"center\" width=\"100%\">");

                results.Append("<table cellpadding=\"2\" cellspacing=\"0\" border=\"0\">");
                results.Append("<tr>");
                results.Append("<td align=\"left\"><span class=\"OrderOptionsRowHeader\">" + AppLogic.GetString("order.cs.15", ThisCustomer.SkinID, ViewInLocaleSetting) + "</span></td>");
                results.Append("<td align=\"center\"><span class=\"OrderOptionsRowHeader\">" + AppLogic.GetString("order.cs.16", ThisCustomer.SkinID, ViewInLocaleSetting) + "</span></td>");
                results.Append("<td align=\"center\"><span class=\"OrderOptionsRowHeader\">" + AppLogic.GetString("order.cs.17", ThisCustomer.SkinID, ViewInLocaleSetting) + "</span></td>");
                results.Append("</tr>");
                foreach (String s in OrderOptions.Split('^'))
                {
                    String[] flds = s.Split('|');
                    results.Append("<tr>");
                    results.Append("<td align=\"left\">");
                    String ImgUrl = AppLogic.LookupImage("OrderOption", Convert.ToString(Localization.ParseUSInt(flds[0])), "icon", ThisCustomer.SkinID, ViewInLocaleSetting);
                    if (ImgUrl.Length != 0 && ImgUrl.IndexOf("nopicture") == -1)
                    {
                        results.Append("<img src=\"" + ImgUrl + "\" border=\"0\" align=\"absmiddle\">&nbsp;");
                    }
                    results.Append("<span class=\"OrderOptionsName\">" + flds[1] + "</span></td>");
                    results.Append("<td width=\"150\" align=\"center\"><span class=\"OrderOptionsPrice\">" + flds[2] + "</span></td>");
                    results.Append("<td width=\"150\" align=\"center\"><img src=\"" + AppLogic.LocateImageURL("skins/skin_" + ThisCustomer.SkinID.ToString() + "/images/selected.gif") + "\" align=\"absmiddle\"></td>");
                    results.Append("</tr>");
                }
                results.Append("</table>");

                results.Append("<br>&nbsp;<br>");
                results.Append("</div>");
            }

            return results.ToString();
        }

        public virtual string ToUpper(string sStrValue)
        {
            InputValidator IV = new InputValidator("ToUpper");
            String StrValue = IV.ValidateString("StrValue", sStrValue);
            return StrValue.ToUpperInvariant();
        }

        public virtual string ToLower(string sStrValue)
        {
            InputValidator IV = new InputValidator("ToLower");
            String StrValue = IV.ValidateString("StrValue", sStrValue);
            return StrValue.ToLowerInvariant();
        }

        public virtual string OrderShippingCalculation(string PaymentMethod, string ShippingMethod, string sShippingTotal, int ShippingCalculationID, int ShipAddresses, bool IsAllDownloadComponents, bool IsAllFreeShippingComponents, bool IsAllSystemComponents)
        {
            string Locale = ThisCustomer.LocaleSetting;
            decimal ShippingTotal = Localization.ParseDBDecimal(sShippingTotal);

            StringBuilder results = new StringBuilder("");

            if (!AppLogic.AppConfigBool("SkipShippingOnCheckout"))
            {
                results.Append("<tr>");
                String ShowShipText = CommonLogic.IIF(ShipAddresses > 1, String.Empty, ShippingMethod);
                // strip out RT shipping cost, if any:
                if (IsAllDownloadComponents || IsAllFreeShippingComponents || IsAllSystemComponents)
                {
                    ShowShipText = AppLogic.GetString("order.cs.1", ThisCustomer.SkinID, ThisCustomer.LocaleSetting);
                }
                else if (ShowShipText.IndexOf("|") != -1)
                {
                    String[] ss2 = ShowShipText.Split('|');
                    try
                    {
                        ShowShipText = ss2[0].Trim();
                    }
                    catch { }
                }
                if (ShippingCalculationID == 4)
                {
                    ShowShipText = AppLogic.GetString("order.cs.2", ThisCustomer.SkinID, ThisCustomer.LocaleSetting);
                }

                if (ShowShipText.Length != 0)
                {
                    results.Append("<td align=\"right\" valign=\"top\" >" + AppLogic.GetString("order.cs.18", ThisCustomer.SkinID, ThisCustomer.LocaleSetting) + " (" + ShowShipText + "):</td>");
                }
                else
                {
                    results.Append("<td align=\"right\" valign=\"top\" >" + AppLogic.GetString("order.cs.18", ThisCustomer.SkinID, ThisCustomer.LocaleSetting) + ":</td>");
                }
                string st = AppLogic.GetString("order.cs.3", ThisCustomer.SkinID, ThisCustomer.LocaleSetting);
                if (false == "REQUEST QUOTE".Equals(PaymentMethod, StringComparison.InvariantCultureIgnoreCase))
                {
                    st = FormatCurrencyHelper(ShippingTotal, ThisCustomer.CurrencyCode);
                }
                results.Append("<td align=\"right\" valign=\"top\">" + st + "</td>");
                results.Append("</tr>");
            }
            return results.ToString();
        }

        public bool FileExists(String sFNOrUrl)
        {
            InputValidator IV = new InputValidator("FileExists");
            String FNOrUrl = IV.ValidateString("FNOrUrl", sFNOrUrl);
            // Name can be relative URL or physical file path!
            return CommonLogic.FileExists(CommonLogic.SafeMapPath(FNOrUrl));
        }

        // returns Payment Method cleaned (no spaces, or weird chars, all uppercased)
        public virtual string CleanPaymentMethod(String sPM)
        {
            InputValidator IV = new InputValidator("CleanPaymentMethod");
            String PM = IV.ValidateString("PM", sPM);
            return AppLogic.CleanPaymentMethod(PM);
        }

        // returns Payment Gateway cleaned (no spaces, or weird chars, all uppercased)
        public virtual string CleanPaymentGateway(String sGW)
        {
            InputValidator IV = new InputValidator("CleanPaymentGateway");
            String GW = IV.ValidateString("GW", sGW);
            return AppLogic.CleanPaymentGateway(GW);
        }

        // returns lowercase of string, invariant culture
        public virtual string StrToLower(String sS)
        {
            InputValidator IV = new InputValidator("StrToLower");
            String S = IV.ValidateString("S", sS);
            return S.ToLower(CultureInfo.InvariantCulture);
        }

        // returns uppercase of string, invariant culture
        public virtual string StrToUpper(String sS)
        {
            InputValidator IV = new InputValidator("StrToUpper");
            String S = IV.ValidateString("S", sS);
            return S.ToUpper(CultureInfo.InvariantCulture);
        }

        // returns capitalize of string, invariant culture
        public virtual string StrCapitalize(String sS)
        {
            InputValidator IV = new InputValidator("StrCapitalize");
            String S = IV.ValidateString("S", sS);
            return CommonLogic.Capitalize(S);
        }

        // returns trim of string
        public virtual string StrTrim(String sS)
        {
            InputValidator IV = new InputValidator("StrTrim");
            String S = IV.ValidateString("S", sS);
            return S.Trim();
        }

        // returns trim start of string
        public virtual string StrTrimStart(String sS)
        {
            InputValidator IV = new InputValidator("StrTrimStart");
            String S = IV.ValidateString("S", sS);
            return S.TrimStart();
        }

        // returns trim end of string
        public virtual string StrTrimEnd(String sS)
        {
            InputValidator IV = new InputValidator("StrTrimEnd");
            String S = IV.ValidateString("S", sS);
            return S.TrimEnd();
        }

        // returns string replace
        public virtual string StrReplace(String sS, String sOldValue, String sNewValue)
        {
            InputValidator IV = new InputValidator("StrReplace");
            String S = IV.ValidateString("S", sS);
            String OldValue = IV.ValidateString("OldValue", sOldValue);
            String NewValue = IV.ValidateString("NewValue", sNewValue);
            return S.Replace(OldValue, NewValue);
        }

        // returns string in "plural" form (this is almost impossible to do)!
        public virtual string StrMakePlural(String sS)
        {
            InputValidator IV = new InputValidator("StrMakePlural");
            String S = IV.ValidateString("S", sS);
            return S;
        }

        // returns string in "singular" form (this is almost impossible to do)!
        public virtual string StrMakeSingular(String sS)
        {
            InputValidator IV = new InputValidator("StrMakeSingular");
            String S = IV.ValidateString("S", sS);
            return S;
        }

        //splits a string and puts it inside tags using the specified TagName, e.g. <TagName>value1</TagName><TagName>value2</TagName>..., the valuex will be XML Encoded
        public virtual string SplitString(string sS, string sDelimiter, string sTagName)
        {
            InputValidator IV = new InputValidator("SplitString");
            String S = IV.ValidateString("S", sS);
            String Delimiter = IV.ValidateString("Delimiter", sDelimiter);
            String TagName = IV.ValidateString("TagName", sTagName);
            if (S.Trim().Length == 0)
            {
                return "";
            }

            string tagStart = string.Empty;
            string tagEnd = string.Empty;
            if (TagName.Trim().Length > 0)
            {
                tagStart = "<" + TagName.Trim() + ">";
                tagEnd = "</" + TagName.Trim() + ">";
            }
            StringBuilder tmpS = new StringBuilder();
            char[] delim = Delimiter.ToCharArray();
            foreach (string sv in S.Split(delim))
            {
                tmpS.Append(tagStart + XmlCommon.XmlEncode(sv) + tagEnd);
            }
            return tmpS.ToString();
        }

        public virtual string MicroPayBalance()
        {
            string Locale = ThisCustomer.LocaleSetting;
            if (ThisCustomer != null)
            {
                return FormatCurrencyHelper(AppLogic.GetMicroPayBalance(ThisCustomer.CustomerCode), ThisCustomer.CurrencyCode);
            }
            else
            {
                return FormatCurrencyHelper(AppLogic.GetMicroPayBalance(ThisCustomer.CustomerCode), Currency.GetFeedReferenceCurrencyCode());
            }
        }

        public virtual string StrFormat(string SrcString, string FormatParams, string delimiter)
        {
            char[] delim = delimiter.ToCharArray();
            string[] rParams = FormatParams.Split(delim);
            return String.Format(SrcString, FormatParams);
        }

        public virtual string ReadFile(string FName)
        {
            return CommonLogic.ReadFile(FName, true);
        }

        public virtual string LocateImageURL(string imgUrl)
        {
            return AppLogic.LocateImageURL(imgUrl);
        }

        public virtual string GetNativeShortDateString(string sDateTimeString)
        {
            InputValidator IV = new InputValidator("GetNativeShortDateString");
            DateTime dt = IV.ValidateDateTime("DateTimeString", sDateTimeString);
            return Localization.ToNativeShortDateString(dt);
        }

        public virtual string GetPollBox(String PollID, bool large)
        {
            return AppLogic.GetPollBox(ThisCustomer, PollID, large); 
        }

        public virtual string GetRatingStarsImage(Decimal rating)
        {
            return GetRatingStarsImage(rating, ThisCustomer.SkinID);
        }

        public virtual string GetRatingStarsImage(Decimal rating, int skinID)
        {
            return CommonLogic.BuildStarsImage(rating, skinID);
        }

        public virtual string FormatInterpriseCurrency(string sAmount, string customerCurrencyCode)
        {
            InputValidator validator = new InputValidator("FormatInterpriseCurrency");
            decimal amount = validator.ValidateDecimal("Amount", sAmount);
            return InterpriseHelper.FormatCurrencyForCustomer(amount, customerCurrencyCode);
        }

        public string MakeItemLink(string itemCode)
        {
            return InterpriseHelper.MakeItemLink(itemCode);
        }

        public string MakeItemImageLink(string itemCode, string size)
        {
            string imageUrl = InterpriseHelper.LookUpImageByItemCode(itemCode, size, ThisCustomer);
            string imageLink = string.Format("<img border=\"0\" src=\"{0}\" />", imageUrl);

            return imageLink;
        }

        public string ShowKitItemOptions(int counter, string itemKitCode, string strHidePriceUntilCart)
        {
            InputValidator IV = new InputValidator("ShowKitItemOptions");
            bool hidePriceUntilCart = IV.ValidateBool("HidePriceUntilCart", strHidePriceUntilCart);
            return string.Empty; 
        }

        public string FeaturedEntityLink(String EntityCode, String EntityName)
        {
            return string.Format("{0}-{1}.aspx", EntityCode, EntityName);
        }

        public string MakeEntityLink(String EntityName, String EntityCode)
        {
            return InterpriseHelper.MakeEntityLink(EntityName, EntityCode);
        }

        public string GetGalleryImage(int galleryId, string sizeType)
        {
            return InterpriseHelper.GetGalleryImage(galleryId, sizeType, ThisCustomer.SkinID, ThisCustomer.LocaleSetting);
        }

        public string GetKitPricePackage(string ItemCode, bool withCurrencySymbol)
        {
            String PriceString = String.Empty;
            decimal KitPrice = 0;

            KitPrice = ((decimal)Convert.ToDecimal(InterpriseHelper.InventoryKitPackagePrice(ItemCode, ThisCustomer.CurrencyCode)));


            if (withCurrencySymbol)
            {
                PriceString = ThisCustomer.FormatBasedOnMyCurrency(KitPrice);
            }
            else
            {
                PriceString = KitPrice.ToString();
            }

            return PriceString;
        }

        public int GetFreeStock(string ItemCode)
        {
            return InterpriseHelper.InventoryFreeStock(ItemCode, ThisCustomer);
        }

        public string ProductRatingStars(string ItemCode)
        {
            return InterpriseHelper.InventoryProductRating(ItemCode, ThisCustomer.SkinID, ThisCustomer.LocaleSetting);
        }

        public string GetAccessoryProducts(string ItemCode)
        {
            string result = String.Empty;
            if (this.IsUsingHelperTemplate && CurrentContext.IsRequestingFromMobileMode(ThisCustomer))
            {
                return GetAccessoryProducts(ItemCode, true);
            }
            try
            {
                String S = InterpriseHelper.ShowInventoryAccessoryOptions(ItemCode, true, 100, string.Empty, ThisCustomer, true, true, InterpriseHelper.ViewingPage.Product);
                result = "<br clear=\"all\"/>" + S;
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return result;
        }

        public string GetAlsoPurchasedProducts(string ItemCode)
        {
            string result = String.Empty;
            try
            {
                result = InterpriseHelper.ShowAlsoPurchasedProducts(ItemCode, true, ThisCustomer);
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return result;
        }

        public string GetAlsoViewedProducts(string ItemCode)
        {
            string result = String.Empty;
            try
            {
                result = InterpriseHelper.ShowAlsoViewedProducts(ItemCode, true, ThisCustomer);
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return result;
        }

        /// <summary>
        /// This is used to automatically invoke the design from xmlpackage
        /// </summary>
        public string GetAccessoryProducts(string ItemCode, bool useXmlDesign)
        {
            string result = string.Empty;
            try
            {
                result = InterpriseHelper.ShowInventoryAccessoryOptions(ItemCode, true, 100, string.Empty, ThisCustomer, true, true, InterpriseHelper.ViewingPage.Product, this.XmlPackageHelperTemplate);
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return result;
        }

        public virtual string GetUnitSystemMeasure(int decimalPlacePreferences, string unitMeasureValue)
        {
            try
            {
                return InterpriseHelper.GetInventoryUnitMeasure(ThisCustomer.LocaleSetting, decimalPlacePreferences, unitMeasureValue);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public virtual int GetInventoryPreferencePlaces()
        {
            return InterpriseHelper.GetInventoryDecimalPlacesPreference();
        }

        public virtual string GetUserMeasureUnitSystem()
        {
            return InterpriseHelper.GetUserUnitMeasureSystem(InterpriseHelper.ConfigInstance.UserCode);
        }

        public virtual string GetSplitString(string sStringToSplit, string sSplitChar, string intReturnIndex)
        {
            InputValidator IV = new InputValidator("GetSplitString");
            String StringToSplit = IV.ValidateString("StringToSplit", sStringToSplit);
            String SplitChar = IV.ValidateString("SplitChar", sSplitChar);
            int ReturnIndex = IV.ValidateInt("ReturnIndex", intReturnIndex);
            if (SplitChar.Length == 0)
            {
                SplitChar = ",";
            }
            String[] s = StringToSplit.Split(SplitChar.ToCharArray());
            String tmp = String.Empty;
            try
            {
                tmp = s[ReturnIndex];
            }
            catch { }
            return tmp;
        }
        
        public virtual string ShowStockHints(String sItemCode)
        {
            StringBuilder results = new StringBuilder("");

            if (AppLogic.AppConfigBool("ShowStockHints"))
            {
                results.Append(AppLogic.GetStockHints(sItemCode));
            }
            return results.ToString();
        }

        public virtual string MiniCartProductImage(string intProductID, String sImageFileNameOverride, String sSKU)
        {
            InputValidator IV = new InputValidator("MiniCartProductImage");
            int ProductID = IV.ValidateInt("ProductID", intProductID);
            String ProdPic = String.Empty;

            string results = "";
            bool m_WatermarksEnabled = AppLogic.AppConfigBool("Watermark.Enabled");
            if (m_WatermarksEnabled)
            {
                ProdPic = String.Format("watermark.axd?counter={0}&size=icon", intProductID);
            }
            int MaxWidth = AppLogic.AppConfigNativeInt("MiniCartMaxIconWidth");
            if (MaxWidth == 0)
            {
                MaxWidth = 125;
            }
            int MaxHeight = AppLogic.AppConfigNativeInt("MiniCartMaxIconHeight");
            if (MaxHeight == 0)
            {
                MaxHeight = 125;
            }
            if (ProdPic.Length != 0)
            {
                System.Drawing.Size size = CommonLogic.GetImagePixelSize(ProdPic);
                if (size.Width > MaxWidth)
                {
                    results = "<img align=\"center\" src=\"" + ProdPic + "\" width=\"" + MaxWidth.ToString() + "\" border=\"0\"/><br/>";
                }
                else if (size.Height > MaxHeight)
                {
                    results = "<img align=\"center\" src=\"" + ProdPic + "\" height=\"" + MaxHeight + "\" border=\"0\"><br/>";
                }
                else
                {
                    results = "<img align=\"center\" src=\"" + ProdPic + "\" border=\"0\"/><br/>";
                }
            }
            return results;
        }

        public virtual String GetStoreHTTPLocation(String sTryToUseSSL)
        {
            InputValidator IV = new InputValidator("GetStoreHTTPLocation");
            bool TryToUseSSL = IV.ValidateBool("TryToUseSSL", sTryToUseSSL);
            return AppLogic.GetStoreHTTPLocation(TryToUseSSL);
        }

        public virtual string FormatDecimal(string sDecimalValue, string intFixPlaces)
        {
            InputValidator IV = new InputValidator("FormatDecimal");
            Decimal DecimalValue = IV.ValidateDecimal("DecimalValue", sDecimalValue);
            DecimalValue = Localization.ParseDBDecimal(sDecimalValue);
            int FixPlaces = IV.ValidateInt("intFixPlaces", intFixPlaces);
            DecimalValue = Decimal.Round(DecimalValue, FixPlaces, MidpointRounding.AwayFromZero);
            return DecimalValue.ToString(new CultureInfo(ThisCustomer.LocaleSetting));
        }

        public virtual string FormatStringForLink(string sThisString)
        {
            return CommonLogic.Left(Security.UrlEncode(SE.MungeName(sThisString)), 90); 
        }

        #region RegisterProduct

        public virtual string RegisterProduct(int itemCounter, string itemCode, string itemType)
        {
            return RegisterProduct(itemCounter, itemCode, itemType, true);
        }

        public virtual string RegisterProduct(int itemCounter, string itemCode, string itemType, bool includeMatrixItems)
        {
            if (this.IsUsingHelperTemplate && CurrentContext.IsRequestingFromMobileMode(ThisCustomer))
            {
                return RegisterProduct(itemCounter, itemCode, itemType, includeMatrixItems, true);
            }

            var script = new StringBuilder();

            script.AppendLine();
            script.Append("<script type=\"text/javascript\" >\n");
            script.Append("$add_windowLoad(\n");
            script.Append(" function() { \n");

            switch (itemType)
            {
                case Interprise.Framework.Base.Shared.Const.ITEM_TYPE_KIT:

                    #region KIT_ITEM

                    script.AppendFormat("    var kitProduct = new ise.Products.KitProduct({0}, \"{1}\", \"{2}\");\n", itemCounter, itemCode.ToJavaScriptEscape(), itemType);

                    var kitSerializer = new JSONSerializer(SerializeOption.Fields);

                    ItemWebOption kitSettings = null;
                    if (TempWebOptionSettings == null) { kitSettings = ItemWebOption.GetWebOption(itemCode); }
                    else { kitSettings = TempWebOptionSettings; }

                    if (kitSettings.RestrictedQuantities.Count > 0)
                    {
                        string serializedRestrictedQuantities = kitSerializer.SerializeArray(kitSettings.RestrictedQuantities);
                        script.AppendFormat("    kitProduct.setRestrictedQuantities({0});\n", serializedRestrictedQuantities);
                    }

                    script.AppendFormat("    kitProduct.setMinimumOrderQuantity({0});\n", kitSettings.MinimumOrderQuantity);
                    script.AppendFormat("    kitProduct.setHidePriceUntilCart({0});\n", kitSettings.HidePriceUntilCart.ToString().ToLowerInvariant());
                    script.AppendFormat("    kitProduct.setShowBuyButton({0});\n", kitSettings.ShowBuyButton.ToString().ToLowerInvariant());
                    script.AppendFormat("    kitProduct.setImageZoomOption('{0}');\n", kitSettings.ZoomOption.ToString());

                    var availableKitUnitMeasures = ProductPricePerUnitMeasure.GetAll(itemCode, ThisCustomer, kitSettings.HidePriceUntilCart);
                    string serializedKitUnitMeasureIntrinsics = kitSerializer.SerializeArray(availableKitUnitMeasures);
                    script.AppendFormat("    kitProduct.setUnitMeasureIntrinsics({0});\n", serializedKitUnitMeasureIntrinsics);

                    script.AppendFormat("    kitProduct.setHasVat({0});\n", AppLogic.AppConfigBool("VAT.Enabled").ToString().ToLowerInvariant());
                    script.AppendFormat("    kitProduct.setVatSetting({0});\n", ((int)ThisCustomer.VATSettingReconciled).ToString());

                    script.AppendFormat("    kitProduct.setQuantityRegEx('{0}','{1}','{2}');\n", CommonLogic.IIF(AppLogic.IsAllowFractional, AppLogic.AllowedQuantityWithDecimalRegEx(ThisCustomer.LocaleSetting), 
                        AppLogic.AllowedQuantityWithNoDecimalRegEx(ThisCustomer.LocaleSetting)).Replace("\\", "\\\\"),
                        Localization.GetNumberDecimalSeparatorLocaleString(ThisCustomer.LocaleSetting), Localization.GetNumberZeroLocaleString(ThisCustomer.LocaleSetting));

                    var kitImageData = ProductImageData.Get(itemCounter, itemCode, Interprise.Framework.Base.Shared.Const.ITEM_TYPE_KIT, 0);
                    string serializedKitImageData = kitSerializer.Serialize(kitImageData);
                    script.AppendFormat("    kitProduct.setImageData({1});\n", itemCounter, serializedKitImageData);

                    var kitComposition = KitItemData.GetKitComposition(ThisCustomer, itemCounter, itemCode);

                    int gctr = 1;
                    foreach (var group in kitComposition.Groups)
                    {

                        switch (group.Type)
                        {
                            case "Required":
                                script.AppendFormat("    var kitGroup_{0} = new ise.Products.KitProductItemRequiredGroup({0}, '{1}', '{2}');\n", group.Id, group.Code, group.CurrencySymbol);
                                break;
                            case "Optional":
                                script.AppendFormat("    var kitGroup_{0} = new ise.Products.KitProductItemOptionalGroup({0}, '{1}', '{2}');\n", group.Id, group.Code, group.CurrencySymbol);
                                break;
                            case "Multi-Select":
                                script.AppendFormat("    var kitGroup_{0} = new ise.Products.KitProductItemMultiSelectGroup({0}, '{1}', '{2}');\n", group.Id, group.Code, group.CurrencySymbol);
                                break;

                        }

                        script.AppendFormat("    kitProduct.registerGroup(kitGroup_{0});\n", group.Id);

                        int ictr = 1;
                        foreach (var item in group.Items)
                        {
                            script.AppendFormat("    var kitItem_{0}_{1} = new ise.Products.KitProductItem({2}, \"{3}\", \"{4}\", \"{5}\", {6} );\n", 
                                                    gctr, ictr, item.Id, item.Code.ToJavaScriptEscape(), item.Type, item.Name.ToJavaScriptEscape(), item.IsSelected.ToString().ToLowerInvariant());
                            script.AppendFormat("    kitGroup_{2}.registerKitItem(kitItem_{0}_{1});\n", gctr, ictr, group.Id);

                            //Clear first the freestock to hide
                            item.UnitMeasures.ForEach(unitMeasure =>
                            {
                                unitMeasure.freeStock = Decimal.Zero;
                                var kitemItemSettings = ItemWebOption.GetWebOption(item.Code);

                                if ((kitemItemSettings.HidePriceUntilCart) ||
                                        (AppLogic.AppConfigBool("WholesaleOnlySite") &&
                                        ThisCustomer.DefaultPrice != Interprise.Framework.Base.Shared.Const.BUSINESS_TYPE_WHOLESALE))
                                {
                                    unitMeasure.price = Decimal.Zero;
                                    unitMeasure.priceFormatted = String.Empty;
                                    unitMeasure.promotionalPrice = Decimal.Zero;
                                    unitMeasure.promotionalPriceFormatted = String.Empty;
                                }
                            });

                            string serializedKitItemUnitMeasureIntrinsics = kitSerializer.SerializeArray(item.UnitMeasures);
                            script.AppendFormat("    kitItem_{0}_{1}.setUnitMeasureIntrinsics({2});\n", gctr, ictr, serializedKitItemUnitMeasureIntrinsics);
                            script.AppendFormat("    kitItem_{0}_{1}.setHasVat({2});\n", gctr, ictr, AppLogic.AppConfigBool("VAT.Enabled").ToString().ToLowerInvariant());
                            script.AppendFormat("    kitItem_{0}_{1}.setVatSetting({2});\n", gctr, ictr, ((int)ThisCustomer.VATSettingReconciled).ToString());

                            script.AppendFormat("    kitItem_{0}_{1} = ise.Products.ProductController.registerProduct(kitItem_{0}_{1});\n", gctr, ictr);
                            ictr++;
                        }

                        script.AppendFormat("    kitGroup_{0}.inspect();\n", group.Id);
                        gctr++;
                    }

                    script.AppendFormat("    kitProduct = ise.Products.ProductController.registerProduct(kitProduct);\n");
                    break;

                    #endregion

                case Interprise.Framework.Base.Shared.Const.ITEM_TYPE_MATRIX_GROUP:

                    #region Matrix

                    script.AppendFormat("    var matrixGroupProduct = new ise.Products.MatrixGroupProduct({0}, '{1}', '{2}');\n", itemCounter, Security.JavascriptEscape(itemCode), itemType);

                    var matrixGroupSerializer = new JSONSerializer(SerializeOption.Fields);

                    ItemWebOption matrixGroupSettings = null;
                    if (TempWebOptionSettings == null) { matrixGroupSettings = ItemWebOption.GetWebOption(itemCode); }
                    else { matrixGroupSettings = TempWebOptionSettings; }

                    if (matrixGroupSettings.RestrictedQuantities.Count > 0)
                    {
                        string serializedRestrictedQuantities = matrixGroupSerializer.SerializeArray(matrixGroupSettings.RestrictedQuantities);
                        script.AppendFormat("    matrixGroupProduct.setRestrictedQuantities({0});\n", serializedRestrictedQuantities);
                    }
                    script.AppendFormat("    matrixGroupProduct.setMinimumOrderQuantity({0});\n", matrixGroupSettings.MinimumOrderQuantity);
                    script.AppendFormat("    matrixGroupProduct.setHidePriceUntilCart({0});\n", matrixGroupSettings.HidePriceUntilCart.ToString().ToLowerInvariant());
                    script.AppendFormat("    matrixGroupProduct.setShowBuyButton({0});\n", matrixGroupSettings.ShowBuyButton.ToString().ToLowerInvariant());
                    script.AppendFormat("    matrixGroupProduct.setImageZoomOption('{0}');\n", matrixGroupSettings.ZoomOption.ToString());

                    var availableMatrixGroupUnitMeasures = ProductPricePerUnitMeasure.GetAll(itemCode, ThisCustomer, matrixGroupSettings.HidePriceUntilCart);
                    string serializedMatrixGroupUnitMeasureIntrinsics = matrixGroupSerializer.SerializeArray(availableMatrixGroupUnitMeasures);
                    script.AppendFormat("    matrixGroupProduct.setUnitMeasureIntrinsics({0});\n", serializedMatrixGroupUnitMeasureIntrinsics);

                    script.AppendFormat("    matrixGroupProduct.setHasVat({0});\n", AppLogic.AppConfigBool("VAT.Enabled").ToString().ToLowerInvariant());
                    script.AppendFormat("    matrixGroupProduct.setVatSetting({0});\n", ((int)ThisCustomer.VATSettingReconciled).ToString());

                    script.AppendFormat("    matrixGroupProduct.setQuantityRegEx('{0}');\n", CommonLogic.IIF(AppLogic.IsAllowFractional, AppLogic.AllowedQuantityWithDecimalRegEx(ThisCustomer.LocaleSetting), AppLogic.AllowedQuantityWithNoDecimalRegEx(ThisCustomer.LocaleSetting)).Replace("\\", "\\\\"));

                    var groupImageData = ProductImageData.Get(itemCounter, itemCode, Interprise.Framework.Base.Shared.Const.ITEM_TYPE_MATRIX_GROUP, 0);
                    //string serializedMatrixGroupImageData = matrixGroupSerializer.Serialize(groupImageData);
                    string serializedMatrixGroupImageData = InterpriseSuiteEcommerceCommon.Tool.JSONHelper.Serialize<ProductImageData>(groupImageData);
                    script.AppendFormat("    matrixGroupProduct.setImageData({1});\n", itemCounter, serializedMatrixGroupImageData);

                    if (includeMatrixItems)
                    {
                        var matrixItems = MatrixItemData.GetMatrixItems(itemCounter, itemCode, true);
                        var itemCodes = matrixItems.Select(m => m.ItemCode);
                        var matrixItemSettings = ItemWebOption.GetWebOptions(itemCodes);

                        int ctr = 1;
                        foreach (var item in matrixItems)
                        {
                            script.AppendFormat("    var matrixProduct{0} = new ise.Products.MatrixProduct({1}, '{2}', \"{3}\");\n", 
                                                                                                            ctr, 
                                                                                                            item.Counter,
                                                                                                            item.ItemCode.ToJavaScriptEscape(), 
                                                                                                            Interprise.Framework.Base.Shared.Const.ITEM_TYPE_MATRIX_ITEM);

                            script.AppendFormat("    matrixGroupProduct.registerMatrixProduct(matrixProduct{0});\n", ctr);

                            var matrixItemSerializer = new JSONSerializer(SerializeOption.Fields);
                            var curSettings = matrixItemSettings.First(s => s.ItemCode == item.ItemCode);

                            //var matrixItemSettings = ItemWebOption.GetWebOption(item.ItemCode);
                            if (curSettings.RestrictedQuantities.Count > 0)
                            {
                                string serializedRestrictedQuantities = matrixItemSerializer.SerializeArray(curSettings.RestrictedQuantities);
                                script.AppendFormat("    matrixProduct{0}.setRestrictedQuantities({1});\n", ctr, serializedRestrictedQuantities);
                            }

                            script.AppendFormat("    matrixProduct{0}.setMinimumOrderQuantity({1});\n", ctr, curSettings.MinimumOrderQuantity);
                            script.AppendFormat("    matrixProduct{0}.setHidePriceUntilCart({1});\n", ctr, curSettings.HidePriceUntilCart.ToString().ToLowerInvariant());
                            script.AppendFormat("    matrixProduct{0}.setShowBuyButton({1});\n", ctr, curSettings.ShowBuyButton.ToString().ToLowerInvariant());
                            script.AppendFormat("    matrixProduct{0}.setImageZoomOption('{1}');\n", ctr, curSettings.ZoomOption.ToString());

                            var matrixItemAvailableUnitMeasures = ProductPricePerUnitMeasure.GetAll(item.ItemCode, ThisCustomer, curSettings.HidePriceUntilCart);
                            string serializedMatrixItemUnitMeasureIntrinsics = matrixItemSerializer.SerializeArray(matrixItemAvailableUnitMeasures);
                            script.AppendFormat("    matrixProduct{0}.setUnitMeasureIntrinsics({1});\n", ctr, serializedMatrixItemUnitMeasureIntrinsics);

                            script.AppendFormat("    matrixProduct{0}.setHasVat({1});\n", ctr, AppLogic.AppConfigBool("VAT.Enabled").ToString().ToLowerInvariant());
                            script.AppendFormat("    matrixProduct{0}.setVatSetting({1});\n", ctr, ((int)ThisCustomer.VATSettingReconciled).ToString());

                            string serializedAttributesFor = matrixItemSerializer.SerializeArray(item.Attributes);
                            script.AppendFormat("    matrixProduct{0}.setAttributes({1});\n", ctr, serializedAttributesFor);

                            string serializedMatrixItemImageData = matrixItemSerializer.Serialize(item.ImageData);
                            script.AppendFormat("    matrixProduct{0}.setImageData({1});\n", ctr, serializedMatrixItemImageData);

                            ctr++;
                        }
                    }

                    script.AppendFormat("    matrixGroupProduct = ise.Products.ProductController.registerProduct(matrixGroupProduct);\n");
                    break;

                    #endregion

                default:

                    #region Stock

                    script.AppendFormat("    var product = new ise.Products.Product({0}, \"{1}\", \"{2}\");\n", itemCounter, itemCode.ToJavaScriptEscape(), itemType.ToJavaScriptEscape());

                    var serializer = new JSONSerializer(SerializeOption.Fields);

                    var settings = ItemWebOption.GetWebOption(itemCode);
                    if (settings.RestrictedQuantities.Count > 0)
                    {
                        string serializedRestrictedQuantities = serializer.SerializeArray(settings.RestrictedQuantities);
                        script.AppendFormat("    product.setRestrictedQuantities({0});\n", serializedRestrictedQuantities);
                    }

                    script.AppendFormat("    product.setMinimumOrderQuantity({0});\n", settings.MinimumOrderQuantity);
                    script.AppendFormat("    product.setHidePriceUntilCart({0});\n", settings.HidePriceUntilCart.ToString().ToLowerInvariant());
                    script.AppendFormat("    product.setShowBuyButton({0});\n", settings.ShowBuyButton.ToString().ToLowerInvariant());
                    script.AppendFormat("    product.setImageZoomOption('{0}');\n", settings.ZoomOption.ToString());

                    var availableUnitMeasures = ProductPricePerUnitMeasure.GetAll(itemCode, ThisCustomer, settings.HidePriceUntilCart);
                    string serializedUnitMeasureIntrinsics = serializer.SerializeArray(availableUnitMeasures);
                    script.AppendFormat("    product.setUnitMeasureIntrinsics({0});\n", serializedUnitMeasureIntrinsics);

                    script.AppendFormat("    product.setHasVat({0});\n", AppLogic.AppConfigBool("VAT.Enabled").ToString().ToLowerInvariant());
                    script.AppendFormat("    product.setVatSetting({0});\n", ((int)ThisCustomer.VATSettingReconciled).ToString());

                    ProductImageData imageData = ProductImageData.Get(itemCounter, itemCode, itemType, 0);
                    string serializedImageData = serializer.Serialize(imageData);
                    script.AppendFormat("    product.setImageData({0});\n", serializedImageData);

                    switch (itemType)
                    {
                        case Interprise.Framework.Base.Shared.Const.ITEM_TYPE_ELECTRONIC_DOWNLOAD:
                        case Interprise.Framework.Base.Shared.Const.ITEM_TYPE_SERVICE:
                        case Interprise.Framework.Base.Shared.Const.ITEM_TYPE_NON_STOCK:

                            script.AppendFormat("    product.setQuantityRegEx('{0}');\n",
                                                            AppLogic.AllowedQuantityWithDecimalRegEx(ThisCustomer.LocaleSetting)
                                                                    .ToJavaScriptEscape()
                                                                    .Replace("\\", "\\\\"));
                            break;
                        default:
                            script.AppendFormat("    product.setQuantityRegEx('{0}');\n", 
                                AppLogic.IsAllowFractional? AppLogic.AllowedQuantityWithDecimalRegEx(ThisCustomer.LocaleSetting):
                                                            AppLogic.AllowedQuantityWithNoDecimalRegEx(ThisCustomer.LocaleSetting)
                                                                    .ToJavaScriptEscape()
                                                                    .Replace("\\", "\\\\"));
                            break;
                    }

                    script.AppendFormat("    product = ise.Products.ProductController.registerProduct(product);\n");
                    break;

                    #endregion

            }           

            script.Append(" }\n");
            script.Append(");\n");
            script.Append("</script>\n");
            script.AppendLine();

            return script.ToString();
        }

        public virtual string RegisterProduct(int itemCounter, string itemCode, string itemType, bool includeMatrixItems, bool useXmlDesign)
        {
            var script = new StringBuilder();

            switch (itemType)
            {
                case Interprise.Framework.Base.Shared.Const.ITEM_TYPE_KIT:
                    script.AppendFormat("    var kitProduct = new ise.Products.KitProduct({0}, '{1}', '{2}');\n", itemCounter, Security.JavascriptEscape(itemCode), itemType);

                    var kitSerializer = new JSONSerializer(SerializeOption.Fields);

                    ItemWebOption kitSettings = null;
                    if (TempWebOptionSettings == null) { kitSettings = ItemWebOption.GetWebOption(itemCode); }
                    else { kitSettings = TempWebOptionSettings; }

                    if (kitSettings.RestrictedQuantities.Count > 0)
                    {
                        string serializedRestrictedQuantities = kitSerializer.SerializeArray(kitSettings.RestrictedQuantities);
                        script.AppendFormat("    kitProduct.setRestrictedQuantities({0});\n", serializedRestrictedQuantities);
                    }

                    script.AppendFormat("    kitProduct.setMinimumOrderQuantity({0});\n", kitSettings.MinimumOrderQuantity);
                    script.AppendFormat("    kitProduct.setHidePriceUntilCart({0});\n", kitSettings.HidePriceUntilCart.ToString().ToLowerInvariant());
                    script.AppendFormat("    kitProduct.setShowBuyButton({0});\n", kitSettings.ShowBuyButton.ToStringLower());

                    var availableKitUnitMeasures = ProductPricePerUnitMeasure.GetAll(itemCode, ThisCustomer);
                    string serializedKitUnitMeasureIntrinsics = kitSerializer.SerializeArray(availableKitUnitMeasures);

                    script.AppendFormat("    kitProduct.setUnitMeasureIntrinsics({0});\n", serializedKitUnitMeasureIntrinsics);

                    script.AppendFormat("    kitProduct.setHasVat({0});\n", AppLogic.AppConfigBool("VAT.Enabled").ToString().ToLowerInvariant());
                    script.AppendFormat("    kitProduct.setVatSetting({0});\n", ((int)ThisCustomer.VATSettingReconciled).ToString());

                    script.AppendFormat("    kitProduct.setQuantityRegEx('{0}','{1}','{2}');\n", CommonLogic.IIF(AppLogic.IsAllowFractional, AppLogic.AllowedQuantityWithDecimalRegEx(ThisCustomer.LocaleSetting),
                        AppLogic.AllowedQuantityWithNoDecimalRegEx(ThisCustomer.LocaleSetting)).Replace("\\", "\\\\"),
                        Localization.GetNumberDecimalSeparatorLocaleString(ThisCustomer.LocaleSetting), Localization.GetNumberZeroLocaleString(ThisCustomer.LocaleSetting));

                    var kitImageData = ProductImageData.Get(itemCounter, itemCode, Interprise.Framework.Base.Shared.Const.ITEM_TYPE_KIT, 0);
                    string serializedKitImageData = kitSerializer.Serialize(kitImageData);
                    script.AppendFormat("    kitProduct.setImageData({1});\n", itemCounter, serializedKitImageData);

                    var kitComposition = KitItemData.GetKitComposition(ThisCustomer, itemCounter, itemCode);

                    int gctr = 1;
                    foreach (var group in kitComposition.Groups)
                    {
                        switch (group.Type)
                        {
                            case "Required":
                                script.AppendFormat("    var kitGroup_{0} = new ise.Products.KitProductItemRequiredGroup({0}, '{1}');\n", group.Id, group.Code);
                                break;
                            case "Optional":
                                script.AppendFormat("    var kitGroup_{0} = new ise.Products.KitProductItemOptionalGroup({0}, '{1}');\n", group.Id, group.Code);
                                break;
                            case "Multi-Select":
                                script.AppendFormat("    var kitGroup_{0} = new ise.Products.KitProductItemMultiSelectGroup({0}, '{1}');\n", group.Id, group.Code);
                                break;

                        }

                        script.AppendFormat("    kitProduct.registerGroup(kitGroup_{0});\n", group.Id);

                        int ictr = 1;
                        foreach (var item in group.Items)
                        {
                            script.AppendFormat("    var kitItem_{0}_{1} = new ise.Products.KitProductItem({2}, \"{3}\", \"{4}\", \"{5}\", {6} );\n", gctr, ictr, item.Id, Security.JavascriptEscape(item.Code), item.Type, Security.JavascriptEscape(item.Name), item.IsSelected.ToString().ToLowerInvariant());
                            script.AppendFormat("    kitGroup_{2}.registerKitItem(kitItem_{0}_{1});\n", gctr, ictr, group.Id);

                            string serializedKitItemUnitMeasureIntrinsics = kitSerializer.SerializeArray(item.UnitMeasures);
                            script.AppendFormat("    kitItem_{0}_{1}.setUnitMeasureIntrinsics({2});\n", gctr, ictr, serializedKitItemUnitMeasureIntrinsics);
                            script.AppendFormat("    kitItem_{0}_{1}.setHasVat({2});\n", gctr, ictr, AppLogic.AppConfigBool("VAT.Enabled").ToString().ToLowerInvariant());
                            script.AppendFormat("    kitItem_{0}_{1}.setVatSetting({2});\n", gctr, ictr, ((int)ThisCustomer.VATSettingReconciled).ToString());

                            script.AppendFormat("    kitItem_{0}_{1} = ise.Products.ProductController.registerProduct(kitItem_{0}_{1});\n", gctr, ictr);
                            ictr++;
                        }

                        script.AppendFormat("    kitGroup_{0}.inspect();\n", group.Id);
                        gctr++;
                    }

                    script.AppendFormat("    kitProduct = ise.Products.ProductController.registerProduct(kitProduct);\n");
                    break;

                case Interprise.Framework.Base.Shared.Const.ITEM_TYPE_MATRIX_GROUP:
                    script.AppendFormat("    var matrixGroupProduct = new ise.Products.MatrixGroupProduct({0}, '{1}', '{2}');\n", itemCounter, Security.JavascriptEscape(itemCode), itemType);

                    var matrixGroupSerializer = new JSONSerializer(SerializeOption.Fields);

                    ItemWebOption matrixGroupSettings = null;
                    if (TempWebOptionSettings == null) { matrixGroupSettings = ItemWebOption.GetWebOption(itemCode); }
                    else { matrixGroupSettings = TempWebOptionSettings; }

                    if (matrixGroupSettings.RestrictedQuantities.Count > 0)
                    {
                        string serializedRestrictedQuantities = matrixGroupSerializer.SerializeArray(matrixGroupSettings.RestrictedQuantities);
                        script.AppendFormat("    matrixGroupProduct.setRestrictedQuantities({0});\n", serializedRestrictedQuantities);
                    }
                    script.AppendFormat("    matrixGroupProduct.setMinimumOrderQuantity({0});\n", matrixGroupSettings.MinimumOrderQuantity);
                    script.AppendFormat("    matrixGroupProduct.setHidePriceUntilCart({0});\n", matrixGroupSettings.HidePriceUntilCart.ToString().ToLowerInvariant());
                    script.AppendFormat("    matrixGroupProduct.setShowBuyButton({0});\n", matrixGroupSettings.ShowBuyButton.ToString().ToLowerInvariant());

                    var availableMatrixGroupUnitMeasures = ProductPricePerUnitMeasure.GetAll(itemCode, ThisCustomer);
                    string serializedMatrixGroupUnitMeasureIntrinsics = matrixGroupSerializer.SerializeArray(availableMatrixGroupUnitMeasures);

                    script.AppendFormat("    matrixGroupProduct.setUnitMeasureIntrinsics({0});\n", serializedMatrixGroupUnitMeasureIntrinsics);

                    script.AppendFormat("    matrixGroupProduct.setHasVat({0});\n", AppLogic.AppConfigBool("VAT.Enabled").ToString().ToLowerInvariant());
                    script.AppendFormat("    matrixGroupProduct.setVatSetting({0});\n", ((int)ThisCustomer.VATSettingReconciled).ToString());

                    script.AppendFormat("    matrixGroupProduct.setQuantityRegEx('{0}');\n", CommonLogic.IIF(AppLogic.IsAllowFractional, AppLogic.AllowedQuantityWithDecimalRegEx(ThisCustomer.LocaleSetting), AppLogic.AllowedQuantityWithNoDecimalRegEx(ThisCustomer.LocaleSetting)).Replace("\\", "\\\\"));

                    var groupImageData = ProductImageData.Get(itemCounter, itemCode, Interprise.Framework.Base.Shared.Const.ITEM_TYPE_MATRIX_GROUP, 0);
                    string serializedMatrixGroupImageData = matrixGroupSerializer.Serialize(groupImageData);
                    script.AppendFormat("    matrixGroupProduct.setImageData({1});\n", itemCounter, serializedMatrixGroupImageData);

                    if (includeMatrixItems)
                    {
                        var matrixItems = MatrixItemData.GetMatrixItems(itemCounter, itemCode, true);
                        var itemCodes = matrixItems.Select(m => m.ItemCode);
                        var matrixItemSettings = ItemWebOption.GetWebOptions(itemCodes);

                        int ctr = 1;
                        foreach (var item in matrixItems)
                        {
                            script.AppendFormat("    var matrixProduct{0} = new ise.Products.MatrixProduct({1}, '{2}', '{3}');\n", ctr, item.Counter, Security.JavascriptEscape(item.ItemCode), Interprise.Framework.Base.Shared.Const.ITEM_TYPE_MATRIX_ITEM);
                            script.AppendFormat("    matrixGroupProduct.registerMatrixProduct(matrixProduct{0});\n", ctr);

                            var matrixItemSerializer = new JSONSerializer(SerializeOption.Fields);
                            var curSettings = matrixItemSettings.First(s => s.ItemCode == item.ItemCode);

                            if (curSettings.RestrictedQuantities.Count > 0)
                            {
                                string serializedRestrictedQuantities = matrixItemSerializer.SerializeArray(curSettings.RestrictedQuantities);
                                script.AppendFormat("    matrixProduct{0}.setRestrictedQuantities({1});\n", ctr, serializedRestrictedQuantities);
                            }
                            script.AppendFormat("    matrixProduct{0}.setMinimumOrderQuantity({1});\n", ctr, curSettings.MinimumOrderQuantity);
                            script.AppendFormat("    matrixProduct{0}.setHidePriceUntilCart({1});\n", ctr, curSettings.HidePriceUntilCart.ToString().ToLowerInvariant());
                            script.AppendFormat("    matrixProduct{0}.setShowBuyButton({1});\n", ctr, curSettings.ShowBuyButton.ToString().ToLowerInvariant());

                            var matrixItemAvailableUnitMeasures = ProductPricePerUnitMeasure.GetAll(item.ItemCode, ThisCustomer);
                            string serializedMatrixItemUnitMeasureIntrinsics = matrixItemSerializer.SerializeArray(matrixItemAvailableUnitMeasures);
                            script.AppendFormat("    matrixProduct{0}.setUnitMeasureIntrinsics({1});\n", ctr, serializedMatrixItemUnitMeasureIntrinsics);

                            script.AppendFormat("    matrixProduct{0}.setHasVat({1});\n", ctr, AppLogic.AppConfigBool("VAT.Enabled").ToString().ToLowerInvariant());
                            script.AppendFormat("    matrixProduct{0}.setVatSetting({1});\n", ctr, ((int)ThisCustomer.VATSettingReconciled).ToString());

                            string serializedAttributesFor = matrixItemSerializer.SerializeArray(item.Attributes);
                            script.AppendFormat("    matrixProduct{0}.setAttributes({1});\n", ctr, serializedAttributesFor);

                            string serializedMatrixItemImageData = matrixItemSerializer.Serialize(item.ImageData);
                            script.AppendFormat("    matrixProduct{0}.setImageData({1});\n", ctr, serializedMatrixItemImageData);

                            ctr++;
                        }
                    }
                    script.AppendFormat("    matrixGroupProduct = ise.Products.ProductController.registerProduct(matrixGroupProduct);\n");
                    break;

                default:

                    var scriptXml = new XElement(DomainConstants.XML_ROOT_NAME);
                    scriptXml.Add(new XElement(DomainConstants.XML_SECTION_TYPE, XMLSectionType.REGISTER_STOCK_PRODUCT_JSCRIPT));

                    var settings = ItemWebOption.GetWebOption(itemCode);
                    var availableUnitMeasures = ProductPricePerUnitMeasure.GetAll(itemCode, ThisCustomer);
                    bool vatEnabled = AppLogic.AppConfigBool("VAT.Enabled");
                    var imageData = ProductImageData.Get(itemCounter, itemCode, itemType, 0);

                    string quantityRegex = string.Empty;
                    switch (itemType)
                    {
                        case Interprise.Framework.Base.Shared.Const.ITEM_TYPE_ELECTRONIC_DOWNLOAD:
                        case Interprise.Framework.Base.Shared.Const.ITEM_TYPE_SERVICE:
                        case Interprise.Framework.Base.Shared.Const.ITEM_TYPE_NON_STOCK:
                            quantityRegex = AppLogic.AllowedQuantityWithDecimalRegEx(ThisCustomer.LocaleSetting).Replace("\\", "\\\\");
                            break;
                        default:
                            quantityRegex = CommonLogic.IIF(AppLogic.IsAllowFractional, Security.JavascriptEscape(AppLogic.AllowedQuantityWithDecimalRegEx(ThisCustomer.LocaleSetting).Replace("\\", "\\\\")), 
                                                            AppLogic.AllowedQuantityWithNoDecimalRegEx(ThisCustomer.LocaleSetting));
                            break;
                    }

                    var jsonProductDTO = new JSONRegisterProductDTO
                    {
                        ItemCounter = itemCounter.ToString(),
                        ItemCode = Security.JavascriptEscape(itemCode),
                        ItemType = itemType,
                        RestrictedQuantities = CommonLogic.IIF(settings.RestrictedQuantities.Count > 0, settings.RestrictedQuantities, null),
                        MinimumOrderQuantity = settings.MinimumOrderQuantity,
                        HidePriceUntilCart = settings.HidePriceUntilCart,
                        ShowBuyButton = settings.ShowBuyButton,
                        UnitMeasureIntrinsic = availableUnitMeasures,
                        VatEnabled = vatEnabled,
                        VatSetting = (int)ThisCustomer.VATSettingReconciled,
                        ImageData = imageData,
                        QuantityRegex = string.Format("{0}", quantityRegex)
                    };

                    string jsonFormat = JSONHelper.Serialize<JSONRegisterProductDTO>(jsonProductDTO);
                    scriptXml.Add(new XElement("REGISTER_PRODUCT_JSON_PARAM", jsonFormat));

                    string outputScript = new XmlPackage2(this.XmlPackageHelperTemplate, scriptXml).TransformString();
                    return outputScript;
            }

            return script.ToString();
        }

        #endregion

        #region MatrixAttributes

        public virtual string MatrixAttributes(int itemCounter, string itemCode, string itemType, string align)
        {
            if (this.IsUsingHelperTemplate && CurrentContext.IsRequestingFromMobileMode(ThisCustomer))
            {
                return MatrixAttributes(itemCounter, itemCode, itemType, align, true);
            }

            if (itemType != Interprise.Framework.Base.Shared.Const.ITEM_TYPE_MATRIX_GROUP)
            {
                return "&nbsp";
            }

            var output = new StringBuilder();

            string alignBreak = "&nbsp";
            if (align.Equals("vertical", StringComparison.InvariantCultureIgnoreCase) || 
                align.Equals("v", StringComparison.InvariantCultureIgnoreCase))
            {
                alignBreak = "<br />";
            }

            var matrixAttributesByCode = new Dictionary<string, MatrixAttribute>();

            using (var con = DB.NewSqlConnection())
            {
                con.Open();
                using (var reader = DB.GetRSFormat(con, "exec eCommerceGetMatrixGroupAttributes @ItemCode = {0}, @LanguageCode = {1}", DB.SQuote(itemCode), DB.SQuote(Customer.Current.LanguageCode)))
                {
                    while (reader.Read())
                    {
                        string attributeCode = DB.RSField(reader, "AttributeCode");
                        string attributeDescription = DB.RSField(reader, "AttributeDescription");

                        string attributeValueCode = DB.RSField(reader, "AttributeValueCode");
                        string attributeValueDescription = DB.RSField(reader, "AttributeValueDescription");

                        MatrixAttribute currentAttribute = null;
                        if (!matrixAttributesByCode.ContainsKey(attributeCode))
                        {
                            currentAttribute = new MatrixAttribute(attributeCode);
                            currentAttribute.AttributeCode = attributeCode;
                            currentAttribute.AttributeDescription = attributeDescription;

                            matrixAttributesByCode.Add(attributeCode, currentAttribute);
                        }

                        currentAttribute = matrixAttributesByCode[attributeCode];

                        currentAttribute.Values.Add(new MatrixAttributeValue(attributeValueCode, attributeValueDescription));
                    }
                }
            }

            output.AppendFormat("<div id=\"pnlMatrixAttribute_Error_{0}\" class=\"MatrixAttributeError\" ></div>", itemCounter);
            output.AppendFormat("<div id=\"pnlMatrixAttribute_SelectCaption_{0}\" style=\"display: none;\"></div>", itemCounter);

            int ctr = 1;
            foreach (string attributeCodeAsKey in matrixAttributesByCode.Keys)
            {
                var currentAttribute = matrixAttributesByCode[attributeCodeAsKey];

                output.AppendFormat("<select id=\"MatrixAttribute_{0}_{1}\" class=\"matrix-selector\" name=\"MatrixAttribute_{0}_{1}\">\n", itemCounter, ctr);
                // select header
                output.AppendFormat("    <option value=\"{0}\" >{1} {2}</option>\n",
                    currentAttribute.AttributeCode.ToHtmlEncode(),
                    AppLogic.GetString("showproduct.aspx.35", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true).ToHtmlEncode(),
                    currentAttribute.AttributeDescription.ToHtmlEncode()
                );
                foreach (var value in currentAttribute.Values)
                {
                    output.AppendFormat("    <option value=\"{0}\" >{1}</option>\n", 
                        value.AttributeValue.ToUrlEncode(),
                        value.AttributeValueDescription.ToHtmlEncode());
                }

                output.Append("</select>\n");
                output.Append(alignBreak);
                ctr++;
            }

            StringBuilder script = new StringBuilder();
            script.AppendLine();
            script.Append("<script type=\"text/javascript\" language=\"Javascript\" >\n");
            script.Append("$add_windowLoad(\n");
            script.Append(" function() { ");

            script.AppendFormat("    ise.StringResource.registerString('showproduct.aspx.39', '{0}');\n", AppLogic.GetString("showproduct.aspx.39", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true));
            script.AppendFormat("    ise.StringResource.registerString('showproduct.aspx.40', '{0}');\n", AppLogic.GetString("showproduct.aspx.40", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true));

            script.AppendFormat("    var product = ise.Products.ProductController.getProduct({0});\n", itemCounter);

            script.AppendFormat("    var matrixGroupControl = new ise.Products.MatrixAttributeGroupControl({0});\n", itemCounter);
            script.AppendFormat("    matrixGroupControl.setProduct(product);\n");

            // register...
            int rctr = 1;
            foreach (string attributeCodeAsKey in matrixAttributesByCode.Keys)
            {
                script.AppendFormat("    var matrixAttrControl_{1} = new ise.Products.MatrixAttributeControl('MatrixAttribute_{0}_{1}', '{2}');\n", itemCounter, rctr, Security.JavascriptEscapeClean(attributeCodeAsKey));
                script.AppendFormat("    matrixGroupControl.registerAttributeControl(matrixAttrControl_{0});\n", rctr);
                rctr++;
            }

            script.Append(" }\n");
            script.Append(");\n");
            script.Append("</script>\n");
            script.AppendLine();

            output.Append(script.ToString());

            return output.ToString();
        }

        public virtual string MatrixAttributes(int itemCounter, string itemCode, string itemType, string align, bool useXmlDesign)
        {
            if (itemType != Interprise.Framework.Base.Shared.Const.ITEM_TYPE_MATRIX_GROUP)
            {
                return string.Empty;
            }

            var xml = new XElement(DomainConstants.XML_ROOT_NAME);
            xml.Add(new XElement(DomainConstants.XML_SECTION_TYPE, XMLSectionType.DISPLAY_MATRIX_ATTRIBUTES));
            xml.Add(new XElement("ITEM_COUNTER", itemCounter));

            var output = new StringBuilder();

            var matrixAttributesByCode = new Dictionary<string, MatrixAttribute>();
            using (var con = DB.NewSqlConnection())
            {
                con.Open();
                using (var reader = DB.GetRSFormat(con, "exec eCommerceGetMatrixGroupAttributes @ItemCode = {0}, @LanguageCode = {1}", DB.SQuote(itemCode), DB.SQuote(Customer.Current.LanguageCode)))
                {
                    while (reader.Read())
                    {
                        string attributeCode = DB.RSField(reader, "AttributeCode");
                        string attributeDescription = DB.RSField(reader, "AttributeDescription");

                        string attributeValueCode = DB.RSField(reader, "AttributeValueCode");
                        string attributeValueDescription = DB.RSField(reader, "AttributeValueDescription");

                        MatrixAttribute currentAttribute = null;

                        if (!matrixAttributesByCode.ContainsKey(attributeCode))
                        {
                            currentAttribute = new MatrixAttribute(attributeCode);
                            currentAttribute.AttributeCode = attributeCode;
                            currentAttribute.AttributeDescription = attributeDescription;
                            matrixAttributesByCode.Add(attributeCode, currentAttribute);
                        }

                        currentAttribute = matrixAttributesByCode[attributeCode];
                        currentAttribute.Values.Add(new MatrixAttributeValue(attributeValueCode, attributeValueDescription));
                    }
                }
            }

            int ctr = 1;
            matrixAttributesByCode.Keys.ForEach(attKey =>
            {
                var currentAttribute = matrixAttributesByCode[attKey];
                var headerAttibute = new XElement("HEADER_ATTRIBUTE");
                headerAttibute.Add(new XElement("HEADER_ATTRIBUTE_CODE", Security.HtmlEncode(currentAttribute.AttributeCode)));
                headerAttibute.Add(new XElement("HEADER_CUSTOM_TEXT", Security.HtmlEncode(AppLogic.GetString("showproduct.aspx.35", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true))));
                headerAttibute.Add(new XElement("HEADER_ATTRIBUTE_DESCRIPTION", Security.HtmlEncode(currentAttribute.AttributeDescription)));
                headerAttibute.Add(new XElement("HEADER_CTR", ctr));
                headerAttibute.Add(new XElement("ITEM_COUNTER", itemCounter));

                currentAttribute.Values.ForEach(attValues =>
                {
                    var attItem = new XElement("ATTRIBUTE_ITEM");
                    attItem.Add(new XElement("ITEM_ATTRIBUTE_CODE", Security.UrlEncode(attValues.AttributeValue)));
                    attItem.Add(new XElement("ITEM_ATTRIBUTE_DESCRIPTION", Security.HtmlEncode(attValues.AttributeValueDescription)));
                    headerAttibute.Add(attItem);
                });

                xml.Add(headerAttibute);
                ctr++;
            });

            var script = new StringBuilder();
            script.AppendFormat("    ise.StringResource.registerString('showproduct.aspx.39', '{0}');\n", AppLogic.GetString("showproduct.aspx.39", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true));
            script.AppendFormat("    ise.StringResource.registerString('showproduct.aspx.40', '{0}');\n", AppLogic.GetString("showproduct.aspx.40", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true));
            script.AppendFormat("    var product = ise.Products.ProductController.getProduct({0});\n", itemCounter);
            script.AppendFormat("    var matrixGroupControl = new ise.Products.MatrixAttributeGroupControl({0});\n", itemCounter);
            script.AppendFormat("    matrixGroupControl.setProduct(product);\n");

            // register...
            int rctr = 1;
            foreach (string attributeCodeAsKey in matrixAttributesByCode.Keys)
            {
                script.AppendFormat("    var matrixAttrControl_{1} = new ise.Products.MatrixAttributeControl('MatrixAttribute_{0}_{1}', '{2}');\n", itemCounter, rctr, Security.JavascriptEscapeClean(attributeCodeAsKey));
                script.AppendFormat("    matrixGroupControl.registerAttributeControl(matrixAttrControl_{0});\n", rctr);
                rctr++;
            }

            xml.Add(new XElement("ATTRIBUTE_SCRIPT", script.ToString()));
            string outputScript = new XmlPackage2(this.XmlPackageHelperTemplate, xml).TransformString();
            return outputScript;
        }

        #endregion

        #region DisplyQuantity

        private decimal GetInitialAddToCartQuantity()
        {
            //if the default isn't set, use one
            decimal intRetVal = 1;

            if (AppLogic.AppConfig("DefaultAddToCartQuantity").Length > 0)
            {
                intRetVal = AppLogic.AppConfigUSDecimal("DefaultAddToCartQuantity");
            }

            return intRetVal;
        }

        /// <summary>
        /// Display the Quantity input box for the given item.
        /// </summary>
        /// <param name="strItemCounter">The counter of the item to display the quantity box for.</param>
        /// <returns>The html string for displaying the quantity box.</returns>
        public virtual string DisplayQuantity(string strItemCounter, bool blnDisplayPrompt, string itemCode, string strItemType)
        {
            ItemWebOption webOptionSetting = new ItemWebOption();
            decimal intInitialQuanitity = GetInitialAddToCartQuantity();

            InputValidator validator = new InputValidator("DisplayQuantity");
            int intItemCounter = validator.ValidateInt("ItemCounter", strItemCounter);

            StringBuilder sbResults = new StringBuilder("");

            // don't allow file to be downloaded if not yet mapped
            if (strItemType == Interprise.Framework.Base.Shared.Const.ITEM_TYPE_ELECTRONIC_DOWNLOAD)
            {
                DownloadableItem download = DownloadableItem.FindByItemCode(itemCode);
                if (null == download)
                {
                    return "<span>" + AppLogic.GetString("shoppingcart.cs.39", ThisCustomer.SkinID, ThisCustomer.LocaleSetting) + "</span>";
                }

                if (!download.IsPhysicalFileExisting())
                {
                    return "<span>" + AppLogic.GetString("shoppingcart.cs.39", ThisCustomer.SkinID, ThisCustomer.LocaleSetting) + "</span>";
                }
            }

            //other products show the quantity box
            string strPrompt = string.Empty;

            if (blnDisplayPrompt)
            {
                strPrompt = AppLogic.GetString("common.cs.21", ThisCustomer.SkinID, ThisCustomer.LocaleSetting);
            }
            
            sbResults.Append(strPrompt);
            sbResults.Append("<input name=\"Quantity_" + intItemCounter.ToString() + "\" type=\"text\" size=\"3\" maxlength=\"3\" value=\"" + intInitialQuanitity.ToString() + "\">");

            return sbResults.ToString();
        }
        #endregion

        #region DisplayNotifyOnPriceDrop
        public virtual string DisplayNotifyOnPriceDrop(int itemCounter, string itemCode, string ProductURL)
        {
            if (this.IsUsingHelperTemplate && CurrentContext.IsRequestingFromMobileMode(ThisCustomer))
            {
                return DisplayNotifyOnPriceDrop(itemCounter, itemCode, ProductURL, true);
            }

            bool withVat = AppLogic.AppConfigBool("VAT.Enabled") && ThisCustomer.VATSettingReconciled == VatDefaultSetting.Inclusive;

            UnitMeasureInfo um = UnitMeasureInfo.ForItem(itemCode, UnitMeasureInfo.ITEM_DEFAULT);

            decimal promotionalPrice = decimal.Zero;
            decimal price =
            InterpriseHelper.GetSalesPriceAndTax(ThisCustomer.CustomerCode,
                itemCode,
                ThisCustomer.CurrencyCode,
                decimal.One,
                um.Code, withVat,
                ref promotionalPrice);

            StringBuilder output = new StringBuilder();
            if (promotionalPrice == 0)
            {
                if (AppLogic.AppConfigBool("NotifyOnPriceDrop.Enabled"))
                {
                    if (ThisCustomer.IsRegistered)
                    {
                        if (!AppLogic.CheckNotification(ThisCustomer.ContactCode, ThisCustomer.EMail, itemCode, 1))
                        {
                            output.AppendFormat("<input type=\"submit\" name=\"NotifyOnPriceDrop\" id=\"NotifyOnPriceDrop\" onclick=\"ShowProductNotifyPriceDropPopUp('{1}','{2}','{3}','{4}')\" value=\"{0}\" />\n",
                                                AppLogic.GetString("AppConfig.NotifyOnPriceDropButtonPrompt", ThisCustomer.SkinID, ThisCustomer.LocaleSetting),
                                                "1",
                                                itemCode,
                                                HttpContext.Current.Request.Url.AbsoluteUri.Replace(HttpContext.Current.Request.Url.PathAndQuery, "") + HttpContext.Current.Request.ApplicationPath,
                                                AppLogic.GetString("AppConfig.NotifyOnPriceDropMessagePrompt", ThisCustomer.SkinID, ThisCustomer.LocaleSetting));
                            output.Append("</br></br>");
                        }
                        else
                            output.AppendFormat("<input type=\"submit\" id=\"NotifyOnPriceDrop\" disabled=\"disabled\" value=\"{0}\" />\n", AppLogic.GetString("AppConfig.NotifyOnPriceDropMessagePrompt", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true));
                    }
                }
            }
            return output.ToString();
        }

        public virtual string DisplayNotifyOnPriceDrop(int itemCounter, string itemCode, string ProductURL, bool useXmlDesign)
        {
            bool withVat = AppLogic.AppConfigBool("VAT.Enabled") && ThisCustomer.VATSettingReconciled == VatDefaultSetting.Inclusive;
            var um = UnitMeasureInfo.ForItem(itemCode, UnitMeasureInfo.ITEM_DEFAULT);

            decimal promotionalPrice = decimal.Zero;
            decimal price =
            InterpriseHelper.GetSalesPriceAndTax(ThisCustomer.CustomerCode,
                itemCode,
                ThisCustomer.CurrencyCode,
                decimal.One,
                um.Code, withVat,
                ref promotionalPrice);

            string output = string.Empty;
            if (promotionalPrice != 0) return output;

            if (!AppLogic.AppConfigBool("NotifyOnPriceDrop.Enabled")) return output;

            if (!ThisCustomer.IsRegistered) return output;

            var xml = new XElement(DomainConstants.XML_ROOT_NAME);
            xml.Add(new XElement(DomainConstants.XML_SECTION_TYPE, XMLSectionType.DISPLAY_NOTIFYPRICEDROP));

            bool checkNotification = AppLogic.CheckNotification(ThisCustomer.ContactCode, ThisCustomer.EMail, itemCode, 1);
            xml.Add(new XElement("CHECK_NOTIFICATION_PRICE_DROP", checkNotification.ToString().ToLowerInvariant()));
            if (!checkNotification)
            {
                xml.Add(new XElement("ITEM_COUNTER", itemCounter));
                xml.Add(new XElement("BUTTON_PROMPT", AppLogic.GetString("AppConfig.NotifyOnPriceDropButtonPrompt", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true)));
                xml.Add(new XElement("ITEM_CODE", itemCode));
                xml.Add(new XElement("APP_PATH", HttpContext.Current.Request.Url.AbsoluteUri.Replace(HttpContext.Current.Request.Url.PathAndQuery, "") + HttpContext.Current.Request.ApplicationPath));
            }

            xml.Add(new XElement("MESSAGE_PROMPT", AppLogic.GetString("AppConfig.Mobile.NotifyOnPriceDropMessagePrompt", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true)));

            var xmlpackage = new XmlPackage2(this.XmlPackageHelperTemplate, xml);
            return xmlpackage.TransformString();
        }

        #endregion

        #region DisplayNotifyOnItemAvail
        public virtual string DisplayNotifyOnItemAvail(int itemCounter, string itemCode, string ProductURL, string itemType)
        {
            if (this.IsUsingHelperTemplate && CurrentContext.IsRequestingFromMobileMode(ThisCustomer))
            {
                return DisplayNotifyOnItemAvail(itemCounter, itemCode, ProductURL, itemType, true);
            }

            var output = new StringBuilder();
            bool itemIsDropShip = false;
            bool itemIsSpecialOrder = false;
            int freestock = 0;

            if (itemType == Interprise.Framework.Base.Shared.Const.ITEM_TYPE_NON_STOCK ||
                itemType == Interprise.Framework.Base.Shared.Const.ITEM_TYPE_SERVICE ||
                itemType == Interprise.Framework.Base.Shared.Const.ITEM_TYPE_ELECTRONIC_DOWNLOAD ||
                itemType == Interprise.Framework.Base.Shared.Const.ITEM_TYPE_MATRIX_GROUP)
            {
                return output.ToString();
            }

            using (var con = DB.NewSqlConnection())
            {
                con.Open();
                using (var reader = DB.GetRSFormat(con, "SELECT IsDropShip, IsSpecialOrder FROM InventoryItem with (NOLOCK) WHERE ItemCode=" + DB.SQuote(itemCode)))
                {
                    while (reader.Read())
                    {
                        itemIsDropShip = DB.RSFieldBool(reader, "IsDropShip");
                        itemIsSpecialOrder = DB.RSFieldBool(reader, "IsSpecialOrder");
                    }
                }
            }

            if (!itemIsDropShip & !itemIsSpecialOrder)
            {
                freestock = InterpriseHelper.InventoryFreeStock(itemCode, Customer.Current);

                if (freestock <= 0)
                {
                    if (AppLogic.AppConfigBool("NotifyWhenAvail.Enabled"))
                    {
                        if (ThisCustomer.IsRegistered)
                        {
                            if (!AppLogic.CheckNotification(ThisCustomer.ContactCode, ThisCustomer.EMail, itemCode, 0))
                            {
                                output.AppendFormat("<div id=\"pnlNotifyOnItemAvail_{0}\" name=\"pnlNotifyOnItemAvail_{0}\" >\n", itemCounter);
                                output.AppendFormat("<input type=\"submit\" name=\"NotifyOnItemAvail\" id=\"NotifyOnItemAvail\" onclick=\"ShowProductOnItemAvailPopUp('{1}','{2}','{3}','{4}')\" value=\"{0}\" />\n",
                                    AppLogic.GetString("AppConfig.NotifyOnItemAvailButtonPrompt", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true),
                                    "0",
                                    itemCode,
                                    HttpContext.Current.Request.Url.AbsoluteUri.Replace(HttpContext.Current.Request.Url.PathAndQuery, "") + HttpContext.Current.Request.ApplicationPath,
                                    AppLogic.GetString("AppConfig.NotifyOnItemAvailMessagePrompt", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true));

                                output.Append("</br></br>");
                                output.Append("</div>\n");
                            }
                            else
                                output.AppendFormat("<input type=\"submit\" id=\"NotifyOnItemAvail\" disabled=\"disabled\" value=\"{0}\" />\n", AppLogic.GetString("AppConfig.NotifyOnItemAvailMessagePrompt", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true));
                        }
                    }
                }
            }
            return output.ToString();
        }

        public virtual string DisplayNotifyOnItemAvail(int itemCounter, string itemCode, string ProductURL, string itemType, bool useXmlDesign)
        {
            var output = string.Empty;
            bool itemIsDropShip = false;
            bool itemIsSpecialOrder = false;
            int freestock = 0;

            if (itemType == Interprise.Framework.Base.Shared.Const.ITEM_TYPE_NON_STOCK &&
                itemType == Interprise.Framework.Base.Shared.Const.ITEM_TYPE_SERVICE &&
                itemType == Interprise.Framework.Base.Shared.Const.ITEM_TYPE_ELECTRONIC_DOWNLOAD &&
                itemType == Interprise.Framework.Base.Shared.Const.ITEM_TYPE_MATRIX_GROUP) return output;

            using (var con = DB.NewSqlConnection())
            {
                con.Open();
                using (var reader = DB.GetRSFormat(con, "SELECT IsDropShip, IsSpecialOrder FROM InventoryItem with (NOLOCK) WHERE ItemCode=" + DB.SQuote(itemCode)))
                {
                    while (reader.Read())
                    {
                        itemIsDropShip = DB.RSFieldBool(reader, "IsDropShip");
                        itemIsSpecialOrder = DB.RSFieldBool(reader, "IsSpecialOrder");
                    }
                }
            }

            if (itemIsDropShip & itemIsSpecialOrder) return output;

            freestock = InterpriseHelper.InventoryFreeStock(itemCode, Customer.Current);
            if (freestock > 0) return output;

            if (!AppLogic.AppConfigBool("NotifyWhenAvail.Enabled")) return output;

            if (!ThisCustomer.IsRegistered) return output;

            var xml = new XElement(DomainConstants.XML_ROOT_NAME);
            xml.Add(new XElement(DomainConstants.XML_SECTION_TYPE, XMLSectionType.DISPLAY_NOTIFYONITEMAVAIL));

            bool checkNotification = AppLogic.CheckNotification(ThisCustomer.ContactCode, ThisCustomer.EMail, itemCode, 0);
            xml.Add(new XElement("CHECKNOTIFICATION", checkNotification.ToString().ToLowerInvariant()));
            if (!checkNotification)
            {
                xml.Add(new XElement("ITEM_COUNTER", itemCounter));
                xml.Add(new XElement("BUTTON_PROMPT", AppLogic.GetString("AppConfig.NotifyOnItemAvailButtonPrompt", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true)));
                xml.Add(new XElement("ITEM_CODE", itemCode));
                xml.Add(new XElement("APP_PATH", HttpContext.Current.Request.Url.AbsoluteUri.Replace(HttpContext.Current.Request.Url.PathAndQuery, "") + HttpContext.Current.Request.ApplicationPath));
            }

            xml.Add(new XElement("MESSAGE_PROMPT", AppLogic.GetString("AppConfig.Mobile.NotifyOnItemAvailMessagePrompt", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true)));

            var xmlpackage = new XmlPackage2(this.XmlPackageHelperTemplate, xml);
            return xmlpackage.TransformString();
        }

        #endregion

        #region DisplayPrice

        public virtual string DisplayPrice(int itemCounter, string itemCode)
        {
            return DisplayPrice(itemCounter, itemCode, true);
        }

        public virtual string DisplayPrice(int itemCounter, string itemCode, bool displayLabel)
        {
            if (this.IsUsingHelperTemplate && CurrentContext.IsRequestingFromMobileMode(ThisCustomer))
            {
                return DisplayNonKitPrice(itemCounter, itemCode, displayLabel);
            }

            var settings = ItemWebOption.GetWebOption(itemCode);
            if (settings.HidePriceUntilCart)
            {
                return string.Empty;
            }

            if (AppLogic.AppConfigBool("WholesaleOnlySite") &&
                ThisCustomer.DefaultPrice != Interprise.Framework.Base.Shared.Const.BUSINESS_TYPE_WHOLESALE)
            {
                return string.Empty;
            }

            var output = new StringBuilder();
            output.AppendFormat("<div id=\"pnlDisplayPrice_{0}\"></div>\n", itemCounter);

            var script = new StringBuilder();
            script.AppendLine();
            script.Append("<script type=\"text/javascript\" >\n");
            script.Append("$(document).ready(\n");
            script.Append(" function() { ");

            // register string resources
            if (displayLabel)
            {
                script.AppendFormat("    ise.StringResource.registerString('showproduct.aspx.33', '{0}');\n", AppLogic.GetString("showproduct.aspx.33", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true));
            }
            else
            {
                script.AppendFormat("    ise.StringResource.registerString('showproduct.aspx.33', ' ');\n");
            }

            script.AppendFormat("    ise.StringResource.registerString('showproduct.aspx.34', '{0}');\n", AppLogic.GetString("showproduct.aspx.34", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true));
            script.AppendFormat("    ise.StringResource.registerString('showproduct.aspx.37', '{0}');\n", AppLogic.GetString("showproduct.aspx.37", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true));
            script.AppendFormat("    ise.StringResource.registerString('showproduct.aspx.38', '{0}');\n", AppLogic.GetString("showproduct.aspx.38", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true));
            script.AppendFormat("    ise.StringResource.registerString('showproduct.aspx.47', '{0}');\n", AppLogic.GetString("showproduct.aspx.47", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true));
            script.AppendFormat("    ise.StringResource.registerString('showproduct.aspx.63', '{0}');\n", AppLogic.GetString("showproduct.aspx.63", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true));
            script.AppendFormat("    var product = ise.Products.ProductController.getProduct({0});\n", itemCounter);
            script.AppendFormat("    var priceControl = new ise.Products.PriceControl({0}, 'pnlDisplayPrice_{0}');\n", itemCounter);
            script.AppendFormat("    priceControl.setProductWithLabel(product, '{0}');\n", displayLabel.ToString().ToLower());

            script.Append(" }\n");
            script.Append(");\n");
            script.Append("</script>\n");
            script.AppendLine();

            output.Append(script.ToString());

            return output.ToString();
        }

        public virtual string DisplayPrice(int itemCounter, string itemCode, bool displayLabel, string itemType)
        {
            if (this.IsUsingHelperTemplate && CurrentContext.IsRequestingFromMobileMode(ThisCustomer))
            {
                return DisplayWithKitPrice(itemCounter, itemCode, displayLabel, itemType);
            }

            ItemWebOption settings = null;
            if (TempWebOptionSettings == null) { settings = ItemWebOption.GetWebOption(itemCode); }
            else { settings = TempWebOptionSettings; }

            if (settings.HidePriceUntilCart)
            {
                return string.Empty;
            }

            if (AppLogic.AppConfigBool("WholesaleOnlySite") &&
                ThisCustomer.DefaultPrice != Interprise.Framework.Base.Shared.Const.BUSINESS_TYPE_WHOLESALE)
            {
                return string.Empty;
            }
            if (itemType == "Kit")
            {
                var output = new StringBuilder();

                output.AppendFormat("<div id=\"PopUpKitPrice_{0}\">\n", itemCounter);
                output.AppendFormat("   <div><span id=\"PopUpKitPrice_{0}_Price\" ></span>&nbsp;</div>\n", itemCounter, itemType);
                output.AppendFormat("</div>\n");

                var script = new StringBuilder();
                script.AppendLine();
                script.Append("<script type=\"text/javascript\">\n");
                script.Append("$(document).ready(\n");
                script.Append(" function() { ");

                // register string resources
                if (displayLabel)
                {
                    script.AppendFormat("    ise.StringResource.registerString('showproduct.aspx.28', '{0}');\n", AppLogic.GetString("showproduct.aspx.33", ThisCustomer.SkinID, ThisCustomer.LocaleSetting));
                }
                else
                {
                    script.AppendFormat("    ise.StringResource.registerString('showproduct.aspx.28', ' ');\n");
                }

                script.AppendFormat("    var kitId = {0};\n", itemCounter);
                script.Append("    var kitProduct = ise.Products.ProductController.getProduct(kitId);\n");

                script.AppendFormat("    var ctrlPrice = new ise.Products.KitPriceControl({0}, 'PopUpKitPrice_{0}');\n", itemCounter);
                script.AppendFormat("    ctrlPrice.setKitProduct(kitProduct);\n");

                script.AppendFormat("    var product = ise.Products.ProductController.getProduct({0});\n", itemCounter);
                script.Append(" }\n");
                script.Append(");\n");
                script.Append("</script>\n");
                script.AppendLine();

                output.Append(script.ToString());

                return output.ToString();
            }
            else
            {
                StringBuilder output = new StringBuilder();

                output.AppendFormat("<div id=\"pnlDisplayPrice_{0}\">\n", itemCounter);

                output.Append("</div>\n");

                StringBuilder script = new StringBuilder();

                script.AppendLine();
                script.Append("<script type=\"text/javascript\" language=\"Javascript\" >\n");
                script.Append("$add_windowLoad(\n");
                script.Append(" function() { ");

                // register string resources
                if (displayLabel)
                {
                    script.AppendFormat("    ise.StringResource.registerString('showproduct.aspx.33', '{0}');\n", AppLogic.GetString("showproduct.aspx.33", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true));
                }
                else
                {
                    script.AppendFormat("    ise.StringResource.registerString('showproduct.aspx.33', ' ');\n");
                }

                script.AppendFormat("    ise.StringResource.registerString('showproduct.aspx.34', '{0}');\n", AppLogic.GetString("showproduct.aspx.34", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true));
                script.AppendFormat("    ise.StringResource.registerString('showproduct.aspx.37', '{0}');\n", AppLogic.GetString("showproduct.aspx.37", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true));
                script.AppendFormat("    ise.StringResource.registerString('showproduct.aspx.38', '{0}');\n", AppLogic.GetString("showproduct.aspx.38", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true));
                script.AppendFormat("    ise.StringResource.registerString('showproduct.aspx.47', '{0}');\n", AppLogic.GetString("showproduct.aspx.47", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true));
                script.AppendFormat("    ise.StringResource.registerString('showproduct.aspx.63', '{0}');\n", AppLogic.GetString("showproduct.aspx.63", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true));
                script.AppendFormat("    var product = ise.Products.ProductController.getProduct({0});\n", itemCounter);
                script.AppendFormat("    var priceControl = new ise.Products.PriceControl({0}, 'pnlDisplayPrice_{0}');\n", itemCounter);
                script.AppendFormat("    priceControl.setProductWithLabel(product, '{0}');\n", displayLabel.ToString().ToLower());

                script.Append(" }\n");
                script.Append(");\n");
                script.Append("</script>\n");
                script.AppendLine();

                output.Append(script.ToString());

                return output.ToString();
            }
        }

        public virtual string DisplayKitPrice(int itemCounter, string itemCode)
        {
            var output = new StringBuilder();
            decimal totalRate = decimal.Zero;

            string getTotalRateQuery =
            String.Format("exec GetEcommerceKitPrice @ItemKitCode = {0}, @CurrencyCode = {1}, @WebsiteCode = {2}, @IsAnonymous = {3}, @CustomerCode = {4},  @AnonymousCustomerCode = {5}, @ContactCode = {6}",
                   itemCode.ToDbQuote(),
                   ThisCustomer.CurrencyCode.ToDbQuote(),
                   InterpriseHelper.ConfigInstance.WebSiteCode.ToDbQuote(),
                   ThisCustomer.IsNotRegistered ? 1 : 0,
                   ThisCustomer.CustomerCode.IsNullOrEmptyTrimmed() ? "null" : ThisCustomer.CustomerCode.ToDbQuote(),
                   ThisCustomer.AnonymousCustomerCode.ToDbQuote(),
                   ThisCustomer.ContactCode.ToDbQuote()
                   );

           using (var con = DB.NewSqlConnection())
           {
               con.Open();
               using (var reader = DB.GetRSFormat(con, getTotalRateQuery))
               {
                  while (reader.Read())
                  {
                      totalRate = DB.RSFieldDecimal(reader, "TotalRate");
                  }
               }
           }
           output.AppendFormat("<div id=\"PopUpKitPrice_{0}\">\n", itemCounter);
           output.AppendFormat("   <div><span id=\"PopUpKitPrice_{0}_Price\" > " + AppLogic.GetString("showproduct.aspx.33", ThisCustomer.SkinID, ThisCustomer.LocaleSetting) + " " + ThisCustomer.FormatBasedOnMyCurrency(totalRate) + " </span></div>\n", itemCounter);
           output.AppendFormat("</div>\n");

           return output.ToString();
        }

        //Used XMl helper design
        public virtual string DisplayNonKitPrice(int itemCounter, string itemCode, bool displayLabel)
        {
            var settings = ItemWebOption.GetWebOption(itemCode);
            if (settings.HidePriceUntilCart)
            {
                return string.Empty;
            }

            if (AppLogic.AppConfigBool("WholesaleOnlySite") &&
                ThisCustomer.DefaultPrice != Interprise.Framework.Base.Shared.Const.BUSINESS_TYPE_WHOLESALE)
            {
                return string.Empty;
            }

            var xml = new XElement(DomainConstants.XML_ROOT_NAME);
            xml.Add(new XElement(DomainConstants.XML_SECTION_TYPE, XMLSectionType.DISPLAY_PRICE));
            xml.Add(new XElement("ITEM_COUNTER", itemCounter));

            var script = new StringBuilder();
            script.Append("<script type=\"text/javascript\" >\n");
            script.Append("$(document).ready(\n");
            script.Append(" function() { ");
            script.AppendLine("RegisterPriceResources('{0}','{1}','{2}','{3}','{4}',{5},{6})".FormatWith(
                        AppLogic.GetString("showproduct.aspx.33", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true),
                        AppLogic.GetString("showproduct.aspx.34", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true),
                        AppLogic.GetString("showproduct.aspx.37", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true),
                        AppLogic.GetString("showproduct.aspx.38", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true),
                        AppLogic.GetString("showproduct.aspx.47", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true),
                        itemCounter,
                        displayLabel.ToString().ToLower()
                        ));
            script.Append(" }\n");
            script.Append(");\n");
            script.Append("</script>\n");
            script.AppendLine();

            xml.Add(new XElement("PRICE_SCRIPT", script.ToString()));

            var xmlpackage = new XmlPackage2(this.XmlPackageHelperTemplate, xml);
            return xmlpackage.TransformString();
        }

        //Used XMl helper design
        public virtual string DisplayWithKitPrice(int itemCounter, string itemCode, bool displayLabel, string itemType)
        {
            var settings = ItemWebOption.GetWebOption(itemCode);
            if (settings.HidePriceUntilCart)
            {
                return string.Empty;
            }

            if (AppLogic.AppConfigBool("WholesaleOnlySite") &&
                ThisCustomer.DefaultPrice != Interprise.Framework.Base.Shared.Const.BUSINESS_TYPE_WHOLESALE)
            {
                return string.Empty;
            }

            if (itemType == "Kit")
            {
                return GetGenerixKitPrice(itemCounter, itemCode, displayLabel);
            }
            else
            {
                return DisplayNonKitPrice(itemCounter, itemCode, displayLabel);
            }
        }

        //Used XMl helper design
        public virtual string GetGenerixKitPrice(int itemCounter, string itemCode, bool displayLabel)
        {
            var xml = new XElement(DomainConstants.XML_ROOT_NAME);
            xml.Add(new XElement(DomainConstants.XML_SECTION_TYPE, XMLSectionType.DISPLAY_PRICE));
            xml.Add(new XElement("ITEM_COUNTER", itemCounter));
            xml.Add(new XElement("IS_KIT", true));

            var script = new StringBuilder();
            script.Append("<script type=\"text/javascript\" >\n");
            script.Append("$(document).ready(\n");
            script.Append(" function() { ");
            script.AppendLine("RegisterPriceResources('{0}',{1})".FormatWith(
                                AppLogic.GetString("showproduct.aspx.33", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true),
                                itemCounter,
                                displayLabel.ToString().ToLower()));
            script.Append(" }\n");
            script.Append(");\n");
            script.Append("</script>\n");
            script.AppendLine();
            xml.Add(new XElement("KITPRICE_SCRIPT", script.ToString()));

            var xmlpackage = new XmlPackage2(this.XmlPackageHelperTemplate, xml);
            return xmlpackage.TransformString();
        }

        #endregion

        #region MiniCart

        public string VATSettingForCustomer()
        {
            return ((int)ThisCustomer.VATSettingReconciled).ToString();
        }

        public virtual string GetPriceForMinicartItem(string iTemCode)
        {
            return GetPriceForMinicartItem(iTemCode, string.Empty, string.Empty);
        }

        public virtual string GetPriceForMinicartItem(string iTemCode, string iTemType, string cartID)
        {
            string priceFormatted = string.Empty;
            string vatDisplayIfIncluded = string.Empty;
            decimal promotionalPrice = decimal.Zero;
            decimal tax = decimal.Zero;
            decimal price = decimal.Zero;
            UnitMeasureInfo um;

            Customer thisCustomer = Customer.Current;
            if (iTemType == Interprise.Framework.Base.Shared.Const.ITEM_TYPE_KIT)
            {
                KitComposition kitCartComposition = KitComposition.FromCart(ThisCustomer,
                                                            0,
                                                            iTemCode,
                                                            new Guid(cartID));
                price = kitCartComposition.GetSalesPrice(ref tax);
                if (thisCustomer.VATSettingReconciled == VatDefaultSetting.Inclusive)
                {
                    return price.ToString();
                }
                else
                {
                    return tax.ToString();
                }
                
            }
            else
            {
                if (thisCustomer.VATSettingReconciled == VatDefaultSetting.Inclusive)
                {
                    um = UnitMeasureInfo.ForItem(iTemCode, UnitMeasureInfo.ITEM_DEFAULT);
                    price = InterpriseHelper.GetSalesPriceAndTax(thisCustomer.CustomerCode, iTemCode, thisCustomer.CurrencyCode, decimal.One, um.Code, Convert.ToBoolean("true"), ref promotionalPrice);
                    return price.ToString();
                }
                else
                {
                    um = UnitMeasureInfo.ForItem(iTemCode, UnitMeasureInfo.ITEM_DEFAULT);
                    price = InterpriseHelper.GetSalesPriceAndTax(thisCustomer.CustomerCode, iTemCode, thisCustomer.CurrencyCode, decimal.One, um.Code, Convert.ToBoolean("false"), ref promotionalPrice, ref tax);
                    return tax.ToString();
                }
            }
        }

        public virtual string GetLinkForMatrix(string iTemCode) 
        {
            string href = string.Empty;
            using (var con = DB.NewSqlConnection())
            {
                con.Open();
                using (var reader = DB.GetRSFormat(con, String.Format("SELECT ItemCode FROM InventoryMatrixItem with (NOLOCK) WHERE MatrixItemCode = {0}", DB.SQuote(iTemCode))))
                {
                    if (reader.Read())
                    {
                        href = InterpriseSuiteEcommerceCommon.InterpriseHelper.MakeItemLink(DB.RSField(reader, "ItemCode"));
                    }
                }
            }
            return href;
        }

        #endregion

        #region DisplayImage

        /// <summary>
        /// Used for showing image on email product.
        /// </summary>
        /// <param name="sEntity"></param>
        /// <param name="sId"></param>
        /// <returns></returns>
        public virtual string DisplayImage(string sEntity, string sId)
        {
            //If the entity type is a product and Watermarking is enabled then provid the watermark path instead.
            if (sEntity.ToUpperInvariant() == "PRODUCT" && AppLogic.AppConfigBool("Watermark.Enabled"))
            {
                return String.Format("watermark.axd?counter={0}&size=medium", sId.ToString());
            }
            else
            {
                return AppLogic.LookupImage(sEntity, sId, "medium", ThisCustomer.SkinID, ThisCustomer.LocaleSetting);
            }
        }

        /// <summary>
        /// Used for displaying image on a page
        /// </summary>
        /// <param name="sEntity"></param>
        /// <param name="sId"></param>
        /// <param name="sSize"></param>
        /// <returns></returns>
        public virtual string DisplayImage(string sEntity, string sId, string sSize)
        {
            return DisplayImage(sEntity, sId, sSize, string.Empty, string.Empty);
        }

        /// <summary>
        /// Used for displaying image on a page with an option to set its position vertically.
        /// </summary>
        /// <param name="sEntity"></param>
        /// <param name="sId"></param>
        /// <param name="sSize"></param>
        /// <param name="vposition"></param>
        /// <returns></returns>
        public virtual string DisplayImage(string sEntity, string sId, string sSize, string vposition)
        {
            return DisplayImage(sEntity, sId, sSize, string.Empty, string.Empty, vposition);
        }

        /// <summary>
        /// Used for displaying image on a page
        /// With Alternate Text 'alt' attribute of image tag
        /// </summary>
        /// <param name="sEntity"></param>
        /// <param name="sId"></param>
        /// <param name="sSize"></param>
        /// <param name="sAltText"></param>
        /// <param name="nAltText"></param>
        /// <returns></returns>
        public virtual string DisplayImage(string sEntity, string sId, string sSize, string sAltText, string nAltText)
        {
            return DisplayImage(sEntity, sId, sSize, string.Empty, string.Empty, "center");
        }

        /// <summary>
        /// Used for displaying image on a page with an option to set its position vertically.
        /// With Alternate Text 'alt' attribute of image tag
        /// </summary>
        /// <param name="sEntity">Type of image to load from e.g. category,department, manufacturer, products.</param>
        /// <param name="sId">Counter ID of the sEntity.</param>
        /// <param name="sSize">Type of image to load.</param>
        /// <param name="sAltText">Alternate Text value.</param>
        /// <param name="nAltText">Alternate Text name</param>
        /// <param name="vposition">Vertical position of the image.</param>
        /// <returns></returns>
        public virtual string DisplayImage(string sEntity, string sId, string sSize, string sAltText, string nAltText, string vposition)
        {
            return DisplayImage(sEntity, sId, sSize, sAltText, nAltText, vposition, string.Empty, false);
        }

        /// <summary>
        /// Used for displaying image on a page.
        /// </summary>
        /// <param name="sEntity"></param>
        /// <param name="sId"></param>
        /// <param name="sSize"></param>
        /// <param name="sAltText"></param>
        /// <param name="nAltText"></param>
        /// <param name="vposition"></param>
        /// <param name="sItemCode"></param>
        /// <returns></returns>
        public virtual string DisplayImage(string sEntity, string sId, string sSize, string sAltText, string nAltText, string vposition, string sItemCode, bool locateWithAttributes)
        {
            var IV = new InputValidator("DisplayImage");
            ProductImage img;
            string entity = IV.ValidateString("Entity", sEntity);
            int id = IV.ValidateInt("ID", sId);
            string size = IV.ValidateString("Size", sSize);
            string altText = string.Empty;
            string itemCode = IV.ValidateString("ItemCode", sItemCode);
            string languageCode = AppLogic.GetLanguageCode(ThisCustomer.LocaleSetting);

            if (!string.IsNullOrEmpty(sAltText))
            {
                altText = IV.ValidateString(nAltText, sAltText);
            }

            try
            {
                if (itemCode == string.Empty)
                {
                    img = ProductImage.Locate(entity, id, size);
                    itemCode = InterpriseHelper.GetInventoryItemCode(id);
                }
                else
                {
                    if (locateWithAttributes)
                    {
                        //if not loaded in bulk use the old implementation
                        if (TempProductImageForEntityGrid != null && TempProductImageForEntityGrid.Count() > 0)
                        {
                            img = TempProductImageForEntityGrid.Single(imgItem => imgItem.Code == itemCode);
                        }
                        else
                        {
                            img = ProductImage.Locate(entity, itemCode, size, languageCode);
                        }
                    }
                    else
                    {
                        img = ProductImage.Locate(entity, itemCode, size);
                    }
                }

                string seTitle = string.Empty;
                string seAltText = string.Empty;
                if (locateWithAttributes)
                {
                    seTitle = img.Title;
                    seAltText = img.Alt;
                }
                else
                {
                    AppLogic.GetSEImageAttributes(itemCode, size, languageCode, ref seTitle, ref seAltText);
                }

                if (null != img)
                {
                    var output = new StringBuilder();
                    if (CurrentContext.IsRequestingFromMobileMode(ThisCustomer))
                    {
                        output.AppendFormat("<img id=\"imgEntity_{0}\" class=\"mobileimagesize\" src=\"{1}\" {2} {3} />", id, img.src, (seAltText != string.Empty) ? "alt=\"" + altText + "\"" : string.Empty, (seTitle != string.Empty) ? "title=\"" + seTitle + "\"" : string.Empty);
                    }
                    else
                    {
                        output.AppendFormat("<div id=\"pnlEntityImage_{0}\"  align=\"{1}\" >\n", id, vposition);
                        //output.AppendFormat("    <img id=\"imgEntity_{0}\" data-contentKey=\"{3}\" data-contentType=\"image\" class=\"content\" src=\"{1}\" alt=\"{2}\" border=\"0\" title=\"{3}\" />\n", id, img.src, seAltText, seTitle, itemCode);
                        output.AppendFormat("    <img id=\"imgEntity_{0}\" data-contentEntityType=\"product\" data-contentKey=\"{4}\" data-contentCounter='{5}' data-contentType=\"image\" class=\"content\" src=\"{1}\" alt=\"{2}\" border=\"0\" title=\"{3}\" />\n", id, img.src, seAltText, seTitle, itemCode, id);
                        output.AppendFormat("</div>");
                    }
                    return output.ToString();
                }
            }
            catch { }

            return string.Empty;
        }

        #region New XSLT Extensions
        //note: this is part of the implementation of removing inline html codes in .cs files for easier maintenance (INTVIPTI-2650)
        public virtual string DisplayRatingEx(decimal rating)
        {
            return GetRatingStarsImage(rating, AppLogic.GetCurrentSkinID());
        }
        public virtual string DisplayRatingsExByItemCode(string itemCode)
        {
            RatingCollection rating = RatingCollection.ForItem(itemCode);
            return GetRatingStarsImage(rating.AverageRating, AppLogic.GetCurrentSkinID());
        }
        public virtual string DisplayProductImageEx(int itemCounter, string itemCode, string itemType)
        {
            var xml = new XElement(DomainConstants.XML_ROOT_NAME);
            xml.Add(new XElement(DomainConstants.XML_SECTION_TYPE, XMLSectionType.DISPLAY_PRODUCTIMAGE));
            xml.Add(new XElement("PAGINATION", (AppLogic.AppConfig("ProductImage.Pagination").IsNullOrEmptyTrimmed()) ? "thumbnail" : AppLogic.AppConfig("ProductImage.Pagination")));
            xml.Add(new XElement("SWITCHING", (AppLogic.AppConfig("ProductImage.Switching").IsNullOrEmptyTrimmed()) ? "onmouseover" : AppLogic.AppConfig("ProductImage.Switching")));
            xml.Add(new XElement("ITEM_CODE", itemCode));
            xml.Add(new XElement("ITEM_TYPE", itemType));

            var imgData = ProductImageData.Get(itemCounter, itemCode, itemType, 0);
            var imgDefault = ProductImage.LocateDefaultImage(DomainConstants.EntityProduct, itemCode, "MEDIUM", ThisCustomer.LanguageCode);
            int imgCount = imgData.mediumImages.Count;
            int displayLimit = (AppLogic.AppConfig("ProductImage.DisplayLimit").IsNullOrEmptyTrimmed()) ? int.MaxValue : AppLogic.AppConfigNativeInt("ProductImage.DisplayLimit");


            for (int i = 0; i < imgCount; i++)
            {
                if (i >= displayLimit) { break; }

                var xmlImg = new XElement("IMAGE");
                xmlImg.Add(new XElement("DEFAULT", imgDefault.src.Equals(imgData.mediumImages[i].src)));

                //large
                var xmlImgLarge = new XElement("LARGE");
                xmlImgLarge.Add(new XElement("ALT", imgData.largeImages[i].Alt));
                xmlImgLarge.Add(new XElement("TITLE", imgData.largeImages[i].Title));
                xmlImgLarge.Add(new XElement("SRC", imgData.largeImages[i].src));
                xmlImg.Add(xmlImgLarge);

                //medium
                var xmlImgMedium = new XElement("MEDIUM");
                xmlImgMedium.Add(new XElement("ALT", imgData.mediumImages[i].Alt));
                xmlImgMedium.Add(new XElement("TITLE", imgData.mediumImages[i].Title));
                xmlImgMedium.Add(new XElement("SRC", imgData.mediumImages[i].src));
                xmlImg.Add(xmlImgMedium);

                //micro
                var xmlImgMicro = new XElement("MICRO");
                xmlImgMicro.Add(new XElement("ALT", imgData.microImages[i].Alt));
                xmlImgMicro.Add(new XElement("TITLE", imgData.microImages[i].Title));
                xmlImgMicro.Add(new XElement("SRC", imgData.microImages[i].src));
                xmlImg.Add(xmlImgMicro);

                xml.Add(xmlImg);
            }
            var xmlpackage = new XmlPackage2(this.XmlPackageHelperTemplate, xml);
            return xmlpackage.TransformString();
        }
        public virtual string DisplayCartControlsEx(int itemCounter, string itemCode, string itemType)
        {
            var xml = new XElement(DomainConstants.XML_ROOT_NAME);
            xml.Add(new XElement(DomainConstants.XML_SECTION_TYPE, XMLSectionType.DISPLAY_CARTCONTROL));
            xml.Add(new XElement("ITEM_TYPE", itemType));
            xml.Add(new XElement("ITEM_CODE", itemCode));
            xml.Add(new XElement("ITEM_COUNTER", itemCounter));
            #region ItemSettings
            ItemWebOption settings = ItemWebOption.GetWebOption(itemCode);
            var serializer = new JSONSerializer(SerializeOption.Fields);
            var xmlSettings = new XElement("SETTINGS");
            xmlSettings.Add(new XElement("RESTRICTED_QTY", serializer.SerializeArray(settings.RestrictedQuantities)));
            xmlSettings.Add(new XElement("MIN_ORDER", settings.MinimumOrderQuantity));
            xmlSettings.Add(new XElement("HIDE_PRICE_UNTILCART", settings.HidePriceUntilCart));
            xmlSettings.Add(new XElement("SHOW_BUY_BUTTON", settings.ShowBuyButton));
            xmlSettings.Add(new XElement("REQUIRES_REGISTRATION", settings.RequiresRegistration));
            xmlSettings.Add(new XElement("CALL_TO_ORDER", settings.IsCallToOrder));
            List<ProductPricePerUnitMeasure> unitMeasures = ProductPricePerUnitMeasure.GetAll(itemCode, ThisCustomer);
            xmlSettings.Add(new XElement("UNIT_MEASURES_INTRINSICS", serializer.SerializeArray(unitMeasures)));
            xmlSettings.Add(new XElement("SHOW_ACTUALSTOCK", AppLogic.AppConfigBool("ShowActualInventory")));
            xmlSettings.Add(new XElement("SHOW_STOCKHINTS", AppLogic.AppConfigBool("ShowStockHints")));
            xmlSettings.Add(new XElement("ADDTOCART_ACTION", AppLogic.AppConfig("AddToCartAction")));
            xml.Add(xmlSettings);
            #endregion

            switch (itemType)
            {
                case Interprise.Framework.Base.Shared.Const.ITEM_TYPE_KIT:
                    #region KitOptions
                    var xmlKitOptions = new XElement("KIT_OPTIONS");
                    var kitComposition = KitItemData.GetKitComposition(ThisCustomer, itemCounter, itemCode);
                    xmlKitOptions.Add(new XElement("CURRENCY_SYMBOL", Currency.GetSymbol(ThisCustomer.CurrencyCode)));

                    foreach (var group in kitComposition.Groups)
                    {
                        var xmlKitGroup = new XElement("KIT_GROUP");
                        xmlKitGroup.Add(new XElement("GROUP_TYPE", group.Type));
                        xmlKitGroup.Add(new XElement("GROUP_ID", group.Id));
                        xmlKitGroup.Add(new XElement("GROUP_CODE", group.Code));
                        xmlKitGroup.Add(new XElement("CONTROL_TYPE", group.ControlType));

                        foreach (var item in group.Items)
                        {
                            var xmlKitItem = new XElement("KIT_ITEM");
                            xmlKitItem.Add(new XElement("ITEM_ID", item.Id));
                            xmlKitItem.Add(new XElement("ITEM_TYPE", item.Type));
                            xmlKitItem.Add(new XElement("ITEM_CODE", item.Code));
                            xmlKitItem.Add(new XElement("ITEM_NAME", item.Name));
                            xmlKitItem.Add(new XElement("ITEM_SELECTED", item.IsSelected));

                            foreach (var unit in item.UnitMeasures)
                            {
                                xmlKitItem.Add(new XElement("ITEM_PRICE", unit.price));
                                xmlKitItem.Add(new XElement("ITEM_PRICE_FORMATTED", unit.priceFormatted));
                                xmlKitItem.Add(new XElement("ITEM_FREESTOCK", unit.freeStock));
                                break; //just get the default unit measure
                            }
                            xmlKitGroup.Add(xmlKitItem);
                        }
                        xmlKitOptions.Add(xmlKitGroup);
                    }

                    xml.Add(xmlKitOptions);
                    #endregion
                    break;
                #region MatrixGroup
                case Interprise.Framework.Base.Shared.Const.ITEM_TYPE_MATRIX_GROUP:
                    #region MatrixOptions
                    var xmlMatrixOptions = new XElement("MATRIX_OPTIONS");
                    var matrixAttributesByCode = new Dictionary<string, MatrixAttribute>();
                    using (var con = DB.NewSqlConnection())
                    {
                        con.Open();
                        using (var reader = DB.GetRSFormat(con, "exec eCommerceGetMatrixGroupAttributes @ItemCode = {0}, @LanguageCode = {1}", DB.SQuote(itemCode), DB.SQuote(Customer.Current.LanguageCode)))
                        {
                            while (reader.Read())
                            {
                                string attributeCode = DB.RSField(reader, "AttributeCode");
                                string attributeDescription = DB.RSField(reader, "AttributeDescription");
                                string attributeValueCode = DB.RSField(reader, "AttributeValueCode");
                                string attributeValueDescription = DB.RSField(reader, "AttributeValueDescription");

                                MatrixAttribute currentAttribute = null;
                                if (!matrixAttributesByCode.ContainsKey(attributeCode))
                                {
                                    currentAttribute = new MatrixAttribute(attributeCode);
                                    currentAttribute.AttributeCode = attributeCode;
                                    currentAttribute.AttributeDescription = attributeDescription;

                                    matrixAttributesByCode.Add(attributeCode, currentAttribute);
                                }
                                currentAttribute = matrixAttributesByCode[attributeCode];
                                currentAttribute.Values.Add(new MatrixAttributeValue(attributeValueCode, attributeValueDescription));
                            }
                        }
                    }
                    int ctr = 1;
                    matrixAttributesByCode.Keys.ForEach(attKey =>
                    {
                        var currentAttribute = matrixAttributesByCode[attKey];
                        var headerAttibute = new XElement("HEADER_ATTRIBUTE");
                        headerAttibute.Add(new XElement("HEADER_ATTRIBUTE_CODE", Security.HtmlEncode(currentAttribute.AttributeCode)));
                        headerAttibute.Add(new XElement("HEADER_CUSTOM_TEXT", Security.HtmlEncode(AppLogic.GetString("showproduct.aspx.35", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true))));
                        headerAttibute.Add(new XElement("HEADER_ATTRIBUTE_DESCRIPTION", Security.HtmlEncode(currentAttribute.AttributeDescription)));
                        headerAttibute.Add(new XElement("HEADER_CTR", ctr));
                        headerAttibute.Add(new XElement("ITEM_COUNTER", itemCounter));

                        currentAttribute.Values.ForEach(attValues =>
                        {
                            var attItem = new XElement("ATTRIBUTE_ITEM");
                            attItem.Add(new XElement("ITEM_ATTRIBUTE_CODE", Security.UrlEncode(attValues.AttributeValue)));
                            attItem.Add(new XElement("ITEM_ATTRIBUTE_DESCRIPTION", Security.HtmlEncode(attValues.AttributeValueDescription)));
                            headerAttibute.Add(attItem);
                        });
                        xmlMatrixOptions.Add(headerAttibute);
                        ctr++;
                    });
                    xml.Add(xmlMatrixOptions);
                    #endregion
                    break;
                #endregion
                default: //stock

                    break;
            }

            var xmlpackage = new XmlPackage2(this.XmlPackageHelperTemplate, xml);
            return xmlpackage.TransformString();
        }
        public virtual string DisplayReviewsEx(string itemCode, int sort)
        {
            var xml = new XElement(DomainConstants.XML_ROOT_NAME);
            xml.Add(new XElement(DomainConstants.XML_SECTION_TYPE, XMLSectionType.DISPLAY_REVIEWS));
            xml.Add(new XElement("CUSTOMERCODE", ThisCustomer.CustomerCode));
            xml.Add(new XElement("CONTACTCODE", ThisCustomer.ContactCode));
            xml.Add(new XElement("CUSTOMER_REGISTERED", ThisCustomer.IsRegistered));
            xml.Add(new XElement("ITEMCODE", itemCode));
            xml.Add(new XElement("SORTING_DEFAULT", sort));
            xml.Add(new XElement("LISTONLY", 0));

            var xmlReviews = new XElement("REVIEWS");
            RatingCollection ratings = RatingCollection.ForItem(itemCode);

            //default sorting
            switch (sort)
            {
                case 1: //HelpfulToLessHelpful
                    ratings.Sort(new HelpfulToLessHelpfulRatingSorter());
                    break;
                case 2: //LessHelpfulToHelpful 
                    ratings.Sort(new LessHelpfulToHelpfulRatingSorter());
                    break;
                case 4: //NewToOld 
                    ratings.Sort(new NewToOldRatingSorter());
                    break;
                case 8: //OldToNew 
                    ratings.Sort(new OldToNewRatingSorter());
                    break;
                case 16: //HighToLow 
                    ratings.Sort(new HighToLowRatingSorter());
                    break;
                case 32: //LowToHigh 
                    ratings.Sort(new LowToHighRatingSorter());
                    break;
            }

            foreach (var rating in ratings.Items)
            {
                var xmlReview = new XElement("REVIEW");
                xmlReview.Add(new XElement("LAST_NAME", rating.CustomerLastName));
                xmlReview.Add(new XElement("FIRST_NAME", rating.CustomerFirstName));
                xmlReview.Add(new XElement("COMMENT", rating.Comment));
                xmlReview.Add(new XElement("RATING", rating.ActualRating));
                xmlReview.Add(new XElement("RATING_STARS", DisplayRatingEx(Convert.ToDecimal(rating.ActualRating))));
                xmlReview.Add(new XElement("DATE_CREATED", rating.CreatedOn.ToShortDateString()));
                xmlReview.Add(new XElement("HELPFUL_COUNT", rating.HelpfulCount));
                xmlReview.Add(new XElement("NOTHELPFUL_COUNT", rating.NotHelpfulCount));
                xmlReview.Add(new XElement("REVIEWER_CUSTOMERCODE", rating.CustomerCode));
                xmlReview.Add(new XElement("REVIEWER_CONTACTCODE", rating.ContactCode));
                xmlReviews.Add(xmlReview);
            }
            xml.Add(xmlReviews);

            var xmlpackage = new XmlPackage2(this.XmlPackageHelperTemplate, xml);
            return xmlpackage.TransformString();
        }
        public virtual string DisplayReviewControlEx(string itemCode)
        {
            var xml = new XElement(DomainConstants.XML_ROOT_NAME);
            xml.Add(new XElement(DomainConstants.XML_SECTION_TYPE, XMLSectionType.DISPLAY_REVIEWCONTROL));
            xml.Add(new XElement("ITEM_CODE", itemCode));

            using (SqlConnection con = DB.NewSqlConnection())
            {
                con.Open();
                using (IDataReader rs = DB.GetRSFormat(con, String.Format("SELECT * FROM EcommerceRating with (NOLOCK) WHERE CustomerCode={0} AND ItemCode={1} AND WebsiteCode={2} AND ContactCode={3}", DB.SQuote(ThisCustomer.CustomerCode), DB.SQuote(itemCode), DB.SQuote(InterpriseHelper.ConfigInstance.WebSiteCode), DB.SQuote(ThisCustomer.ContactCode))))
                {
                    if (rs.Read())
                    {
                        xml.Add(new XElement("CURRENT_RATING", DB.RSFieldInt(rs, "Rating")));
                        xml.Add(new XElement("CURRENT_COMMENT", DB.RSField(rs, "Comments")));
                    }
                }
            }

            var xmlpackage = new XmlPackage2(this.XmlPackageHelperTemplate, xml);
            return xmlpackage.TransformString();
        }
        
        public virtual string DisplaySubstituteProductsEx(string itemCode)
        {
            return DisplaySubstituteProductsEx(itemCode, AppLogic.AppConfigBool("ItemPopup.Enabled"), true);
        }
        public virtual string DisplaySubstituteProductsEx(string itemCode, bool itemPopOnclick)
        {
            return DisplaySubstituteProductsEx(itemCode, itemPopOnclick, true);
        }
        public virtual string DisplaySubstituteProductsEx(string itemCode, bool itemPopOnClick, bool showHeader)
        {
            var xml = new XElement(DomainConstants.XML_ROOT_NAME);
            xml.Add(new XElement(DomainConstants.XML_SECTION_TYPE, XMLSectionType.DISPLAY_SUBSTITUTEPRODUCT));
            xml.Add(new XElement("ITEM_CODE", itemCode));
            xml.Add(new XElement("ITEM_POPONCLICK", CommonLogic.IIF(itemPopOnClick, 1, 0)));
            xml.Add(new XElement("SHOW_HEADER", CommonLogic.IIF(showHeader, 1, 0)));

            var xmlSubstituteItems = new XElement("SUBSTITUTE_ITEMS");
            string query = string.Format("exec GetEcommerceSubstituteItems @ItemCode = {0}, @WebSiteCode = {1}, @ContactCode = {2}, @CurrentDate = {3}, @ProductFilterID = {4}",
                            DB.SQuote(itemCode),
                            DB.SQuote(InterpriseHelper.ConfigInstance.WebSiteCode),
                            DB.SQuote(ThisCustomer.ContactCode),
                            DB.SQuote(Localization.DateTimeStringForDB(DateTime.Now)), DB.SQuote(ThisCustomer.ProductFilterID));

            DataSet ds = DB.GetDS(query, false);

            if (ds.Tables[0] != null)
            {
                foreach (DataRow dr in ds.Tables[0].Rows)
                {
                    var xmlItem = new XElement("SUBSTITUTE_ITEM");
                    string displayName = DB.RowField(dr, "ItemDescription");
                    string subItemCode = DB.RowField(dr, "ItemCode");
                    string subItemCounter = DB.RowField(dr, "Counter");
                    if (CommonLogic.IsStringNullOrEmpty(displayName)) { displayName = DB.RowField(dr, "ItemName"); }
                    xmlItem.Add(new XElement("ITEM_NAME", displayName));
                    xmlItem.Add(new XElement("ITEM_CODE", subItemCode));
                    xmlItem.Add(new XElement("ITEM_COUNTER", subItemCounter));
                    xmlItem.Add(new XElement("ITEM_LINK", SE.MakeProductLink(subItemCounter, CommonLogic.Ellipses(displayName, 20, false))));
                    xmlItem.Add(new XElement("ITEM_DISPLAYNAME", CommonLogic.Ellipses(displayName, 20, false)));
                    var imgDefault = ProductImage.LocateDefaultImage(DomainConstants.EntityProduct, subItemCode, "ICON", ThisCustomer.LanguageCode);
                    xmlItem.Add(new XElement("IMG_SRC", imgDefault.src));
                    xmlSubstituteItems.Add(xmlItem);
                }
            }
            xml.Add(xmlSubstituteItems);

            var xmlpackage = new XmlPackage2(this.XmlPackageHelperTemplate, xml);
            return xmlpackage.TransformString();
        }
        
        public virtual string DisplayAccessoryProductsEx(string itemCode)
        {
            return DisplayAccessoryProductsEx(itemCode, AppLogic.AppConfigBool("ItemPopup.Enabled"), true);
        }
        public virtual string DisplayAccessoryProductsEx(string itemCode, bool itemPopOnClick)
        {
            return DisplayAccessoryProductsEx(itemCode, itemPopOnClick, true);
        }
        public virtual string DisplayAccessoryProductsEx(string itemCode, bool itemPopOnClick, bool showHeader)
        {
            var xml = new XElement(DomainConstants.XML_ROOT_NAME);
            xml.Add(new XElement(DomainConstants.XML_SECTION_TYPE, XMLSectionType.DISPLAY_ACCESSORIES));
            xml.Add(new XElement("ITEM_CODE", itemCode));
            xml.Add(new XElement("ITEM_POPONCLICK", CommonLogic.IIF(itemPopOnClick, 1, 0)));
            xml.Add(new XElement("SHOW_HEADER", CommonLogic.IIF(showHeader, 1, 0)));

            var xmlAccessoryItems = new XElement("ACCESSORY_ITEMS");
            string query = string.Format("exec EcommerceGetAccessoryItems @CustomerCode = {0}, @WebSiteCode = {1}, @ItemCode = {2}, @LanguageCode = {3}, @CurrentDate = {4}, @ProductFilterID = {5}, @ContactCode = {6}",
                     DB.SQuote(ThisCustomer.CustomerCode),
                     DB.SQuote(InterpriseHelper.ConfigInstance.WebSiteCode),
                     DB.SQuote(itemCode),
                     DB.SQuote(ThisCustomer.LanguageCode),
                     DB.SQuote(Localization.DateTimeStringForDB(DateTime.Now)),
                     DB.SQuote(ThisCustomer.ProductFilterID),
                     DB.SQuote(ThisCustomer.ContactCode));

            DataSet ds = DB.GetDS(query, false);

            if (ds.Tables[0] != null)
            {
                foreach (DataRow dr in ds.Tables[0].Rows)
                {
                    var xmlItem = new XElement("ACCESSORY_ITEM");
                    string displayName = DB.RowField(dr, "ItemDescription");
                    string subItemCode = DB.RowField(dr, "ItemCode");
                    string subItemCounter = DB.RowField(dr, "Counter");
                    if (CommonLogic.IsStringNullOrEmpty(displayName)) { displayName = DB.RowField(dr, "ItemName"); }
                    xmlItem.Add(new XElement("ITEM_NAME", displayName));
                    xmlItem.Add(new XElement("ITEM_CODE", subItemCode));
                    xmlItem.Add(new XElement("ITEM_COUNTER", subItemCounter));
                    xmlItem.Add(new XElement("ITEM_LINK", SE.MakeProductLink(subItemCounter, CommonLogic.Ellipses(displayName, 20, false))));
                    xmlItem.Add(new XElement("ITEM_DISPLAYNAME", CommonLogic.Ellipses(displayName, 20, false)));
                    var imgDefault = ProductImage.LocateDefaultImage(DomainConstants.EntityProduct, subItemCode, "ICON", ThisCustomer.LanguageCode);
                    xmlItem.Add(new XElement("IMG_SRC", imgDefault.src));
                    xmlAccessoryItems.Add(xmlItem);
                }
            }
            xml.Add(xmlAccessoryItems);

            var xmlpackage = new XmlPackage2(this.XmlPackageHelperTemplate, xml);
            return xmlpackage.TransformString();
        }

        public virtual string DisplayNotifyOnPriceDropEx(string itemCode)
        {
            if (!AppLogic.AppConfigBool("NotifyOnPriceDrop.Enabled")) return string.Empty;
            if (ThisCustomer.IsNotRegistered) return string.Empty;

            var xml = new XElement(DomainConstants.XML_ROOT_NAME);
            xml.Add(new XElement(DomainConstants.XML_SECTION_TYPE, XMLSectionType.DISPLAY_NOTIFYPRICEDROP));

            xml.Add(new XElement("BUTTON_PROMPT", AppLogic.GetString("AppConfig.NotifyOnPriceDropButtonPrompt", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true)));
            xml.Add(new XElement("MESSAGE_PROMPT", AppLogic.GetString("AppConfig.NotifyOnPriceDropMessagePrompt", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true)));
            xml.Add(new XElement("SUBSCRIBED", AppLogic.CheckNotification(ThisCustomer.ContactCode, ThisCustomer.EMail, itemCode, 1)));
            xml.Add(new XElement("ITEM_CODE", itemCode));

            var xmlpackage = new XmlPackage2(this.XmlPackageHelperTemplate, xml);
            return xmlpackage.TransformString();
        }
        public virtual string DisplayNotifyOnItemAvailabilityEx(string itemCode, string itemType)
        {
            if (!AppLogic.AppConfigBool("NotifyWhenAvail.Enabled")) return string.Empty;
            if (ThisCustomer.IsNotRegistered) return string.Empty;
            if (itemType == Interprise.Framework.Base.Shared.Const.ITEM_TYPE_NON_STOCK ||
                itemType == Interprise.Framework.Base.Shared.Const.ITEM_TYPE_SERVICE ||
                itemType == Interprise.Framework.Base.Shared.Const.ITEM_TYPE_ELECTRONIC_DOWNLOAD ||
                itemType == Interprise.Framework.Base.Shared.Const.ITEM_TYPE_MATRIX_GROUP) return string.Empty;

            bool isDropship = false;
            bool isSpecialOrder = false;
            using (var con = DB.NewSqlConnection())
            {
                con.Open();
                using (var reader = DB.GetRSFormat(con, "SELECT IsDropShip, IsSpecialOrder FROM InventoryItem with (NOLOCK) WHERE ItemCode=" + DB.SQuote(itemCode)))
                {
                    while (reader.Read())
                    {
                        isDropship = DB.RSFieldBool(reader, "IsDropShip");
                        isSpecialOrder = DB.RSFieldBool(reader, "IsSpecialOrder");
                    }
                }
            }

            if (isDropship) return string.Empty;
            if (isSpecialOrder) return string.Empty;
            if (InterpriseHelper.InventoryFreeStock(itemCode, ThisCustomer) > 0) return string.Empty;

            var xml = new XElement(DomainConstants.XML_ROOT_NAME);
            xml.Add(new XElement(DomainConstants.XML_SECTION_TYPE, XMLSectionType.DISPLAY_NOTIFYONITEMAVAIL));

            xml.Add(new XElement("BUTTON_PROMPT", AppLogic.GetString("AppConfig.NotifyOnItemAvailButtonPrompt", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true)));
            xml.Add(new XElement("MESSAGE_PROMPT", AppLogic.GetString("AppConfig.NotifyOnItemAvailMessagePrompt", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true)));
            xml.Add(new XElement("SUBSCRIBED", AppLogic.CheckNotification(ThisCustomer.ContactCode, ThisCustomer.EMail, itemCode, 0)));
            xml.Add(new XElement("ITEM_CODE", itemCode));

            var xmlpackage = new XmlPackage2(this.XmlPackageHelperTemplate, xml);
            return xmlpackage.TransformString();
        }
        public virtual string DisplayExpectedShipDateEx(string itemCode, string shippingDate, string itemType)
        {

            if (!AppLogic.AppConfigBool("ShowShipDateInCart")) return string.Empty;
            if (itemType == Interprise.Framework.Base.Shared.Const.ITEM_TYPE_NON_STOCK ||
                itemType == Interprise.Framework.Base.Shared.Const.ITEM_TYPE_SERVICE ||
                itemType == Interprise.Framework.Base.Shared.Const.ITEM_TYPE_ELECTRONIC_DOWNLOAD) return string.Empty;

            DateTime parsedShippingDate = DateTime.MinValue;
            var output = new StringBuilder();

            //Parse the sqlserver shipping Date giving the sql current locale then convert to customer current culture
            DateTime.TryParseExact(shippingDate,
                        Localization.SqlServerLocaleCulture.DateTimeFormat.GetAllDateTimePatterns(), //sql server current locale
                        ThisCustomer.Culture, //to customer current locale
                        DateTimeStyles.None, 
                        out parsedShippingDate);

            if (parsedShippingDate <= DateTime.Now) { return string.Empty; }

            var xml = new XElement(DomainConstants.XML_ROOT_NAME);
            xml.Add(new XElement(DomainConstants.XML_SECTION_TYPE, XMLSectionType.DISPLAY_EXPECTEDSHIPDATE));

            xml.Add(new XElement("EXPECTEDSHIPDATE", string.Format(AppLogic.GetString("showproduct.aspx.48", ThisCustomer.SkinID, ThisCustomer.LocaleSetting), Localization.ToNativeShortDateString(parsedShippingDate))));
            var xmlpackage = new XmlPackage2(this.XmlPackageHelperTemplate, xml);
            return xmlpackage.TransformString();
        }
        #endregion

        public virtual string MobileDisplayImage(string sEntity, string sId, string sSize, string sAltText, string nAltText, string vposition)
        {
            return MobileDisplayImage(sEntity, sId, sSize, sAltText, nAltText, vposition, string.Empty, false);
        }

        public virtual string MobileDisplayImage(string sEntity, string sId, string sSize, string sAltText, string nAltText, string vposition, string sItemCode, bool locateWithAttributes)
        {
            var IV = new InputValidator("DisplayImage");
            ProductImage img;
            string entity = IV.ValidateString("Entity", sEntity);
            int id = IV.ValidateInt("ID", sId);
            string size = IV.ValidateString("Size", sSize);
            string altText = string.Empty;
            string itemCode = IV.ValidateString("ItemCode", sItemCode);
            string languageCode = AppLogic.GetLanguageCode(ThisCustomer.LocaleSetting);

            if (!string.IsNullOrEmpty(sAltText))
            {
                altText = IV.ValidateString(nAltText, sAltText);
            }

            try
            {
                if (itemCode == string.Empty)
                {
                    img = ProductImage.Locate(entity, id, size);
                    itemCode = InterpriseHelper.GetInventoryItemCode(id);
                }
                else
                {
                    if (locateWithAttributes)
                    {
                        img = ProductImage.Locate(entity, itemCode, size, languageCode);
                    }
                    else
                    {
                        img = ProductImage.Locate(entity, itemCode, size);
                    }
                }

                string seTitle = string.Empty;
                string seAltText = string.Empty;
                if (locateWithAttributes)
                {
                    seTitle = img.Title;
                    seAltText = img.Alt;
                }
                else
                {
                    AppLogic.GetSEImageAttributes(itemCode, size, languageCode, ref seTitle, ref seAltText);
                }

                if (null != img)
                {
                    var output = new StringBuilder();
                    if (CurrentContext.IsRequestingFromMobileMode(ThisCustomer))
                    {
                        output.AppendFormat("<img id=\"imgEntity_{0}\" class=\"mobileimagesize\" src=\"{1}\" {2} {3} />", id, img.src, (seAltText != string.Empty) ? "alt=\"" + altText + "\"" : string.Empty, (seTitle != string.Empty) ? "title=\"" + seTitle + "\"" : string.Empty);
                    }
                    else
                    {
                        output.AppendFormat("<div id=\"pnlEntityImage_{0}\"  align=\"{1}\" >\n", id, vposition);
                        output.AppendFormat("    <img id=\"imgEntity_{0}\" src=\"{1}\" alt=\"{2}\" border=\"0\" title=\"{3}\" />\n", id, img.src, seAltText, seTitle);
                        output.AppendFormat("</div>");
                    }
                    return output.ToString();
                }
            }
            catch { }

            return string.Empty;
        }

        #endregion

        #region DisplayProductImage

        /// <summary>
        /// Displays Product Image at page
        /// </summary>
        /// <param name="itemCounter"></param>
        /// <param name="itemCode"></param>
        /// <param name="itemType"></param>
        /// <returns></returns>
        public virtual string DisplayProductImage(int itemCounter, string itemCode, string itemType)
        {
            return DisplayProductImage(itemCounter, itemCode, itemType, "");
        }

        /// <summary>
        /// Displays Product Image at page
        /// With Alternate Text 'alt' attribute of image tag
        /// </summary>
        /// <param name="itemCounter"></param>
        /// <param name="itemCode"></param>
        /// <param name="itemType"></param>
        /// <param name="seAltText"></param>
        /// <returns></returns>
        public virtual string DisplayProductImage(int itemCounter, string itemCode, string itemType, string seAltText)
        {
            if (this.IsUsingHelperTemplate && CurrentContext.IsRequestingFromMobileMode(ThisCustomer))
            {
                return DisplayProductImage(itemCounter, itemCode, itemType, seAltText, true);
            }

            var output = new StringBuilder();
            string sAltText = string.Empty;
            //Additional img prooerties...
            string seTitle = string.Empty;
            string seAltText2 = string.Empty;

            if (!seAltText.IsNullOrEmptyTrimmed())
            {
                sAltText = seAltText;
            }

            //get the title of images
            output.Append("<script type=\"text/javascript\" language=\"Javascript\" >");
            output.Append(string.Format("var imgTitleArray{0} = new Array;", itemCounter));

            string languageCode = AppLogic.GetLanguageCode(ThisCustomer.LocaleSetting);
            var attributes = AppLogic.GetSEImageAttributeByItemCode(itemCode, "LARGE", languageCode);
            foreach (var item in attributes)
            {
                output.Append(string.Format("imgTitleArray{0}.push('" + item.Title + "');", itemCounter));
            }

            output.Append("</script>");
            
            output.AppendFormat("<div id=\"pnlImage_{0}\">\n", itemCounter);

            var attObject = AppLogic.GetSEImageAttributesByObject(itemCode, languageCode);
            seAltText2 = attObject.MediumAlt;
            seTitle = attObject.MediumTitle;

            //output.AppendFormat("<a id=\"lnkLarge_{0}\" class=\"cloud-zoom\"><img data-contentKey=\"{3}\" data-contentType=\"image\" class='product-image-for-matrix-options content' id=\"imgProduct_{0}\" alt=\"{1}\" title=\"{2}\" /></a>\n", itemCounter, attObject.MediumAlt, attObject.MediumTitle, itemCode);
            output.AppendFormat("<div class=\"preview-image\"><a id=\"lnkLarge_{0}\" class=\"cloud-zoom\"><img data-contentKey=\"{3}\"  data-contentEntityType=\"product\" data-contentCounter='{4}' data-contentType=\"image\" class='product-image-for-matrix-options content' id=\"imgProduct_{0}\" alt=\"{1}\" title=\"{2}\" /></a></div>\n", itemCounter, attObject.MediumAlt, attObject.MediumTitle, itemCode, itemCounter);

            // render the multiple images...
            output.AppendFormat("<div id=\"pnlImageMultiples_{0}\" class=\"image-pager\" >\n", itemCounter);

            for (int ctr = 0; ctr < 10; ctr++)
            {
                output.AppendFormat("<img id=\"imgMultiple_{0}_{1}\" style=\"display:none;cursor:hand;cursor:pointer;\" border=\"0\" alt=\"{2}\" title=\"{3}\" />", itemCounter, ctr, ThisCustomer.SkinID, (ctr + 1), seAltText2, seTitle);
            }
            output.Append("</div>\n");

            //AppLogic.GetSEImageAttributes(itemCode, "LARGE", AppLogic.GetLanguageCode(ThisCustomer.LocaleSetting), ref seTitle, ref seAltText2);
            seAltText2 = attObject.LargeAlt;
            seTitle = attObject.LargeTitle;

            List<MatrixItemData> matrixItems = null;
            List<MatrixItemData> onlyMatrixItemsWithSwatches = null;

            if (itemType == Interprise.Framework.Base.Shared.Const.ITEM_TYPE_MATRIX_GROUP)
            {
                matrixItems = MatrixItemData.GetMatrixItems(itemCounter, itemCode, true);

                string swatchOrientation = string.Empty;
                int swatchGroupSize, swatchSpacing;
                swatchGroupSize = swatchSpacing = 0;

                using (var con = DB.NewSqlConnection())
                {
                    con.Open();
                    using (var reader = DB.GetRSFormat(con, "SELECT img.SwatchOrientation, img.SwatchGroupSize, img.SwatchSpacing FROM InventoryMatrixGroup img with (NOLOCK) INNER JOIN InventoryItem i with (NOLOCK) ON i.ItemCode = img.ItemCode WHERE i.ItemCode = {0}", DB.SQuote(itemCode)))
                    {
                        if (reader.Read())
                        {
                            swatchOrientation = DB.RSField(reader, "SwatchOrientation");
                            swatchGroupSize = DB.RSFieldInt(reader, "SwatchGroupSize");
                            swatchSpacing = DB.RSFieldInt(reader, "SwatchSpacing");
                        }
                    }
                }

                // place default values
                if (string.IsNullOrEmpty(swatchOrientation)) swatchOrientation = "horizontal";
                if (swatchGroupSize <= 0) swatchGroupSize = 2;
                if (swatchSpacing <= 0) swatchSpacing = 0;
                
                onlyMatrixItemsWithSwatches = matrixItems
                                                .Where(item => null != item.ImageData && item.ImageData.swatch.exists)
                                                .ToList();

                if (onlyMatrixItemsWithSwatches.Count > 0)
                {
                    var rows = new List<List<MatrixItemData>>();

                    if (swatchOrientation.Equals("horizontal", StringComparison.InvariantCultureIgnoreCase))
                    {
                        int colCtr = 0;
                        int rowCtr = 0;

                        foreach (var item in onlyMatrixItemsWithSwatches)
                        {
                            if (colCtr == 0)
                            {
                                rows.Add(new List<MatrixItemData>());
                            }

                            rows[rowCtr].Add(item);
                            colCtr += 1;
                            if (colCtr == swatchGroupSize)
                            {
                                colCtr = 0;
                                rowCtr++;
                            }
                        }
                    }
                    else
                    {
                        for (int ctr = 0; ctr < swatchGroupSize; ctr++)
                        {
                            var columns = new List<MatrixItemData>();
                            rows.Add(columns);
                        }

                        int rowCtr = 0;

                        foreach (var item in onlyMatrixItemsWithSwatches)
                        {
                            rows[rowCtr].Add(item);
                            rowCtr += 1;
                            if (rowCtr == rows.Count)
                            {
                                rowCtr = 0;
                            }
                        }
                    }

                    output.AppendFormat("<div id=\"pnlImageSwatch_{0}\" >\n", itemCounter);

                    output.AppendFormat("<table id=\"tblImageSwatch_{0}\" border=\"0\" cellspacing=\"{1}\" >\n", itemCounter, swatchSpacing);

                    foreach (var columns in rows)
                    {
                        output.Append("<tr>\n");

                        foreach (var item in columns)
                        {
                            AppLogic.GetSEImageAttributes(item.ItemCode, "MEDIUM", languageCode, ref seTitle, ref seAltText2);
                            output.AppendFormat("        <td> <img id=\"imgSwatch_{0}_{1}\" style=\"cursor:hand;cursor:pointer;\" alt=\"{2}\" title=\"{3}\" /> </td>\n", itemCounter, item.Counter, seAltText2, seTitle);
                        }

                        output.Append("</tr>\n");
                    }

                    output.Append("</table>");

                    output.Append("</div>\n");
                }

            }

            output.Append("<div class=\"clear\"></div> </div>\n");

            var script = new StringBuilder();

            script.AppendLine();
            script.Append("<script type=\"text/javascript\" language=\"Javascript\" >\n");
            script.Append("$add_windowLoad(\n");
            script.Append(" function() { ");

            script.AppendFormat("    var product = ise.Products.ProductController.getProduct({0});\n", itemCounter);
            script.AppendFormat("    var imageControl = new ise.Products.ImageControl({0}, 'imgProduct_{0}');\n", itemCounter);
            script.AppendFormat("    imageControl.setProduct(product);\n");

            // micro image settings...
            script.AppendFormat("    imageControl.setUseMicroImages({0});\n", AppLogic.AppConfigBool("UseImagesForMultiNav").ToString().ToLowerInvariant());
            script.AppendFormat("    imageControl.setHandleHover({0});\n", AppLogic.AppConfigBool("UseRolloverForMultiNav").ToString().ToLowerInvariant());

            for (int ctr = 0; ctr < 10; ctr++)
            {
                int number = ctr + 1;
                string src = src = string.Format("skins/skin_{0}/images/im{1}.gif", ThisCustomer.SkinID, number);

                script.AppendFormat("    var imgMul_{0} = new ise.Products.ImageMultipleControl('imgMultiple_{1}_{0}', {0}, '{2}');\n", ctr, itemCounter, src);
                script.AppendFormat("    imageControl.registerMultipleControl(imgMul_{0});\n", ctr);
            }

            script.AppendFormat("    var lnkLarge = new ise.Products.LargeImageLinkControl('lnkLarge_{0}');\n", itemCounter);
            script.AppendFormat("    imageControl.setLargeImageControl(lnkLarge);\n");

            if (itemType == Interprise.Framework.Base.Shared.Const.ITEM_TYPE_MATRIX_GROUP && null != onlyMatrixItemsWithSwatches)
            {
                for (int ctr = 0; ctr < onlyMatrixItemsWithSwatches.Count; ctr++)
                {
                    var matrixItem = onlyMatrixItemsWithSwatches[ctr];
                    script.AppendFormat("    var imgSwatch_{0} = new ise.Products.ImageSwatchControl({2}, 'imgSwatch_{1}_{2}', '{3}');\n", ctr, itemCounter, matrixItem.Counter, matrixItem.ItemCode.ToUrlEncode());
                    script.AppendFormat("    imageControl.registerSwatchControl(imgSwatch_{0});\n", ctr);
                }
            }

            script.AppendFormat("    imageControl.arrangeDisplay();\n");

            script.Append(" }\n");
            script.Append(");\n");
            script.Append("</script>\n");
            script.AppendLine();

            output.Append(script.ToString());

            return output.ToString();
        }

        /// <summary>
        /// This is used to automatically invoke the design from xmlpackage
        /// </summary>
        public virtual string DisplayProductImage(int itemCounter, string itemCode, string itemType, string seAltText, bool useXmlDesign)
        {
            var xml = new XElement(DomainConstants.XML_ROOT_NAME);
            xml.Add(new XElement(DomainConstants.XML_SECTION_TYPE, XMLSectionType.DISPLAY_PRODUCTIMAGE));
            xml.Add(new XElement("ITEM_COUNTER", itemCounter));
            xml.Add(new XElement("SKIN_ID", ThisCustomer.SkinID));
            xml.Add(new XElement("ITEM_TYPE", itemType));

            string output = string.Empty;
            string sAltText = seAltText;
            string seTitle = string.Empty;
            string seAltText2 = string.Empty;

            AppLogic.GetSEImageAttributes(itemCode, "MEDIUM", AppLogic.GetLanguageCode(ThisCustomer.LocaleSetting), ref seTitle, ref sAltText);
            var xmlImage = new XElement("IMAGE");
            xmlImage.Add(new XElement("ALT_TEXT", sAltText));
            xmlImage.Add(new XElement("TITLE_TEXT", seTitle));
            xml.Add(xmlImage);

            AppLogic.GetSEImageAttributes(itemCode, "MEDIUM", AppLogic.GetLanguageCode(ThisCustomer.LocaleSetting), ref seTitle, ref sAltText);
            var multipleImage = new XElement("MULTIPLE_IMAGE");
            multipleImage.Add(new XElement("ALT_TEXT", sAltText));
            multipleImage.Add(new XElement("TITLE_TEXT", seTitle));
            xml.Add(multipleImage);

            AppLogic.GetSEImageAttributes(itemCode, "MEDIUM", AppLogic.GetLanguageCode(ThisCustomer.LocaleSetting), ref seTitle, ref sAltText);
            var largeImage = new XElement("LARGE_IMAGE");
            largeImage.Add(new XElement("ALT_TEXT", sAltText));
            largeImage.Add(new XElement("TITLE_TEXT", seTitle));
            xml.Add(largeImage);

            List<MatrixItemData> matrixItems = null;
            List<MatrixItemData> onlyMatrixItemsWithSwatches = null;

            if (itemType == Interprise.Framework.Base.Shared.Const.ITEM_TYPE_MATRIX_GROUP)
            {
                matrixItems = MatrixItemData.GetMatrixItems(itemCounter, itemCode, true);

                string swatchOrientation = string.Empty;
                int swatchGroupSize, swatchSpacing;
                swatchGroupSize = swatchSpacing = 0;

                using (var con = DB.NewSqlConnection())
                {
                    con.Open();
                    using (var reader = DB.GetRSFormat(con, "SELECT img.SwatchOrientation, img.SwatchGroupSize, img.SwatchSpacing FROM InventoryMatrixGroup img with (NOLOCK) INNER JOIN InventoryItem i with (NOLOCK) ON i.ItemCode = img.ItemCode WHERE i.ItemCode = {0}", DB.SQuote(itemCode)))
                    {
                        if (reader.Read())
                        {
                            swatchOrientation = DB.RSField(reader, "SwatchOrientation");
                            swatchGroupSize = DB.RSFieldInt(reader, "SwatchGroupSize");
                            swatchSpacing = DB.RSFieldInt(reader, "SwatchSpacing");
                        }
                    }
                }

                // place default values
                if (string.IsNullOrEmpty(swatchOrientation)) swatchOrientation = "horizontal";
                if (swatchGroupSize <= 0) swatchGroupSize = 2;
                if (swatchSpacing <= 0) swatchSpacing = 0;

                onlyMatrixItemsWithSwatches = matrixItems.FindAll(item => { return item.ImageData != null && item.ImageData.swatch.exists; });
                if (onlyMatrixItemsWithSwatches.Count > 0)
                {
                    //lambda anonimous method
                    onlyMatrixItemsWithSwatches.ForEach(m =>
                    {
                        var swatitems = new XElement("JSON_SWATCHITEM");
                        AppLogic.GetSEImageAttributes(m.ItemCode, "MEDIUM", AppLogic.GetLanguageCode(ThisCustomer.LocaleSetting), ref seTitle, ref seAltText2);
                        m.AltText = seAltText2;
                        m.Title = seTitle;

                        swatitems.Add(new XElement("IMG_ALT_TEXT", m.AltText));
                        swatitems.Add(new XElement("IMG_TITLE_TEXT", m.Title));
                        swatitems.Add(new XElement("ITEM_COUNTER", m.Counter));
                        swatitems.Add(new XElement("COUNTER", itemCounter));
                        xml.Add(swatitems);
                    });

                }

            }

            xml.Add(new XElement("USEIMAGESFORMULTINAV", AppLogic.AppConfigBool("UseImagesForMultiNav").ToString().ToLowerInvariant()));
            xml.Add(new XElement("USEROLLOVERFORMULTINAV", AppLogic.AppConfigBool("USEROLLOVERFORMULTINAV").ToString().ToLowerInvariant()));

            var iteratorXml = new XElement("ITERATOR");
            var iterator = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
            iterator.ForEach(ctr => iteratorXml.Add(new XElement("CTR", ctr)));
            xml.Add(iteratorXml);

            if (onlyMatrixItemsWithSwatches != null)
            {
                var MatrixItems = onlyMatrixItemsWithSwatches
                                    .Select(m => new CustomMatrixItem
                                    {
                                        MatrixCounter = m.Counter,
                                        MatrixCode = m.ItemCode
                                    })
                                    .ToArray();
                string json = JSONHelper.Serialize<IEnumerable<CustomMatrixItem>>(MatrixItems);
                xml.Add(new XElement("JSON_MATRIX_ITEMS", json));
            }

            var xmlpackage = new XmlPackage2(this.XmlPackageHelperTemplate, xml);
            return xmlpackage.TransformString();
        }

        #endregion

        public virtual string GetShowProductText()
        {
            return AppLogic.GetString("mobile.showproduct.aspx.cs.53", ThisCustomer.SkinID, ThisCustomer.LocaleSetting);
        }

        public virtual string GetSummaryText()
        {
            return AppLogic.GetString("mobile.showproduct.aspx.cs.54", ThisCustomer.SkinID, ThisCustomer.LocaleSetting);
        }

        public virtual string GetWarrantyText()
        {
            return AppLogic.GetString("mobile.showproduct.aspx.cs.55", ThisCustomer.SkinID, ThisCustomer.LocaleSetting);
        }

        #region DisplayAddToCartForm

        public string DisplayAddToCartForm(int itemCounter, string itemCode, string itemType, string align)
        {
            if (this.IsUsingHelperTemplate)
            {
                return DisplayAddToCartForm(itemCounter, itemCode, itemType, align, true);
            }

            ItemWebOption settings = ItemWebOption.GetWebOption(itemCode);

            //Check for wholesale parameter.
            if (AppLogic.AppConfigBool("WholesaleOnlySite") && ThisCustomer.DefaultPrice.ToLower() != "wholesale")
            {
                settings.ShowBuyButton = false;
            }

            if (!AppLogic.AppConfigBool("ShowBuyButtons"))
            {
                settings.ShowBuyButton = false;
            }
            if (!settings.ShowBuyButton)
            {
                return "&nbsp;";
            }

            if (settings.IsCallToOrder)
            {
                return "<form style=\"margin-top: 0px; margin-bottom: 0px;\"><font class=\"CallToOrder\">" + AppLogic.GetString("common.cs.20", ThisCustomer.SkinID, ThisCustomer.LocaleSetting) + "</font></form>"; // use <form></form> to give same spacing that normal add to cart would have
            }

            if (itemType == Interprise.Framework.Base.Shared.Const.ITEM_TYPE_ELECTRONIC_DOWNLOAD)
            {
                // don't allow file to be downloaded if not yet mapped
                DownloadableItem download = DownloadableItem.FindByItemCode(itemCode);
                if (null == download)
                {
                    return "<span>" + AppLogic.GetString("shoppingcart.cs.39", ThisCustomer.SkinID, ThisCustomer.LocaleSetting) + "</span>";
                }

                if (!download.IsPhysicalFileExisting())
                {
                    return "<span>" + AppLogic.GetString("shoppingcart.cs.39", ThisCustomer.SkinID, ThisCustomer.LocaleSetting) + "</span>";
                }

                //Per defect #75; If the customer is anonymous don't allow them to buy downloadable items.
                if (ThisCustomer.IsNotRegistered)
                {
                    return "<span>" + AppLogic.GetString("shoppingcart.cs.40", ThisCustomer.SkinID, ThisCustomer.LocaleSetting) + "</span>";
                }
            }

            StringBuilder output = new StringBuilder();
            string alignBreak = "&nbsp";
            if (align.Equals("vertical", StringComparison.InvariantCultureIgnoreCase) || 
                align.Equals("v", StringComparison.InvariantCultureIgnoreCase))
            {
                alignBreak = "<br />";
            }

            string action = string.Empty;
            if (settings.RequiresRegistration && ThisCustomer.IsNotRegistered)
            {
                action = MakeItemLink(itemCode.ToString());
            }
            else
            {
                action = "addtocart.aspx?returnurl=" + HttpContext.Current.Server.UrlEncode(CommonLogic.GetThisPageName(false) + "?" + CommonLogic.ServerVariables("QUERY_STRING"));
            }

            output.AppendLine();

            // by default let's make this invisible
            output.AppendFormat("<div id=\"pnlAddToCartForm_{0}\" style=\"display:none;\" >\n", itemCounter);

            output.AppendFormat("<form  class= \"AddToCartclass\" style=\"margin-top: 0px; margin-bottom: 0px;\" method=\"POST\" name=\"AddToCartForm_{0}\" id=\"AddToCartForm_{0}\" action=\"{1}\" >\n", itemCounter, action);
            output.AppendFormat("<input type=\"hidden\" id=\"ProductID_{0}\" name=\"ProductID\" value=\"{0}\" />\n", itemCounter);
            output.AppendFormat("<input type=\"hidden\" id=\"IsWishList_{0}\" name=\"IsWishList\" value=\"0\" />\n", itemCounter);
            output.AppendFormat("<input type=\"hidden\" name=\"UpsellProducts\" id=\"UpsellProducts\" value=\"\">\n");

            bool itemTypeIsKitAndWeAreInEditMode = false;
            string kitCartIDFromQueryString = CommonLogic.QueryStringCanBeDangerousContent("kcid");
            Guid kitCartID = Guid.Empty;

            if (itemType == Interprise.Framework.Base.Shared.Const.ITEM_TYPE_KIT)
            {
                using (SqlConnection con = DB.NewSqlConnection())
                {
                    con.Open();
                    using (IDataReader reader = DB.GetRSFormat(con, "SELECT PricingType FROM InventoryKit with (NOLOCK) WHERE ItemKitCode = {0}", DB.SQuote(itemCode)))
                    {
                        if (reader.Read())
                        {
                            string pricingType = DB.RSField(reader, "PricingType");
                            output.AppendFormat("<input type=\"hidden\" name=\"KitPricingType\" id=\"KitPricingType\" value=\"{0}\">\n", pricingType);
                        }
                    }
                }
                    
                output.Append("<input type=\"hidden\" name=\"KitItems\" id=\"KitItems\" class=\"KitItems\" value=\"\">\n");

                // check if we are in edit mode for this kit item
                if (!CommonLogic.IsStringNullOrEmpty(kitCartIDFromQueryString) &&
                    CommonLogic.IsValidGuid(kitCartIDFromQueryString))
                {
                    itemTypeIsKitAndWeAreInEditMode = true;

                    kitCartID = new Guid(kitCartIDFromQueryString);

                    output.AppendFormat("<input name=\"IsEditKit\" type=\"hidden\" value=\"{0}\">\n", (true).ToString().ToLower());
                    output.AppendFormat("<input name=\"KitCartID\" type=\"hidden\" value=\"{0}\">\n", kitCartID.ToString());
                    output.AppendLine();
                }
            }

            output.Append(alignBreak);
            output.AppendFormat("<span id=\"ctrlQuantity_{0}\"></span>", itemCounter);

            bool hideUnitMeasure = AppLogic.AppConfigBool("HideUnitMeasure");

            if (!hideUnitMeasure)
            {
                output.Append(alignBreak);
                output.AppendFormat("<span id=\"ctrlUnitMeasure_{0}\"></span>", itemCounter);
            }

            output.Append(alignBreak);
            if (settings.ShowBuyButton)
            {
                string addToCartKey = "AppConfig.CartButtonPrompt";
              
                if (itemTypeIsKitAndWeAreInEditMode)
                {
                    addToCartKey = "shoppingcart.cs.33";
                }

                string addToCartCaption = AppLogic.GetString(addToCartKey, ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true);

                output.AppendFormat("<input class=\"site-button content\" data-contentKey=\"{3}\" data-contentValue=\"{1}\" data-contentType=\"string resource\" type=\"submit\" name=\"AddToCart_{0}\" id=\"AddToCart_{0}\" value=\"{1}\" {2} />\n",
                    itemCounter,
                    addToCartCaption,
                    (AppLogic.IsCBNMode()) ? "style=\"display:none\" " : string.Empty, addToCartKey);


            }
            output.Append(alignBreak);

            if (AppLogic.AppConfigBool("ShowWishListButton") && !itemTypeIsKitAndWeAreInEditMode)
            {
                output.AppendFormat("<input class=\"site-button content\" data-contentKey=\"AppConfig.WishButtonPrompt\" data-contentValue=\"{1}\" data-contentType=\"string resource\" type=\"submit\" name=\"AddToWishList_{0}\" id=\"AddToWishList_{0}\" value=\"{1}\" {2} />\n",
                   itemCounter,
                   AppLogic.GetString("AppConfig.WishButtonPrompt", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true),
                   (AppLogic.IsCBNMode()) ? "style=\"display:none\" " : string.Empty);
            }

            output.Append("</form>\n");
            output.Append("</div>\n");

            StringBuilder script = new StringBuilder();

            script.AppendLine();
            script.Append("<script type=\"text/javascript\" language=\"Javascript\" >\n");
            script.Append("$add_windowLoad(\n");
            script.Append(" function() { ");

            // register strings...
            script.AppendFormat("    ise.StringResource.registerString('showproduct.aspx.29', '{0}');\n", AppLogic.GetString("showproduct.aspx.29", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true));
            script.AppendFormat("    ise.StringResource.registerString('showproduct.aspx.30', '{0}');\n", AppLogic.GetString("showproduct.aspx.30", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true));
            script.AppendFormat("    ise.StringResource.registerString('showproduct.aspx.31', '{0}');\n", AppLogic.GetString("showproduct.aspx.31", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true));
            script.AppendFormat("    ise.StringResource.registerString('showproduct.aspx.32', '{0}');\n", AppLogic.GetString("showproduct.aspx.32", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true));
            script.AppendFormat("    ise.StringResource.registerString('showproduct.aspx.36', '{0}');\n", AppLogic.GetString("showproduct.aspx.36", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true));
            script.AppendFormat("    ise.StringResource.registerString('showproduct.aspx.42', '{0}');\n", AppLogic.GetString("showproduct.aspx.42", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true));
            script.AppendFormat("    ise.StringResource.registerString('showproduct.aspx.43', '{0}');\n", AppLogic.GetString("showproduct.aspx.43", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true));
            script.AppendFormat("    ise.StringResource.registerString('showproduct.aspx.46', '{0}');\n", AppLogic.GetString("showproduct.aspx.46", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true));
            script.AppendFormat("    ise.StringResource.registerString('common.cs.22', '{0}');\n", AppLogic.GetString("common.cs.22", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true));
            script.AppendFormat("    ise.StringResource.registerString('common.cs.24', '{0}');\n", AppLogic.GetString("common.cs.24", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true));
    
            script.AppendFormat("    var product = ise.Products.ProductController.getProduct({0});\n", itemCounter);

            script.AppendFormat("    var frm = new ise.Products.AddToCartForm({0});\n", itemCounter);
            script.AppendFormat("    frm.setProduct(product);\n");

            // register the form 
            script.AppendFormat("    ise.Products.AddToCartFormController.registerForm(frm);\n", itemCounter);

            bool ignoreStockLevel = AppLogic.AppConfigBool("Inventory.LimitCartToQuantityOnHand");
            
            script.AppendFormat("    frm.setCheckForFreeStock({0});\n", (ignoreStockLevel).ToString().ToLower());

            // Edit MOde just for kits
            decimal initialQuantity = 0;
            string unitMeasureCode = string.Empty;

            initialQuantity = GetInitialAddToCartQuantity();

            if (itemTypeIsKitAndWeAreInEditMode)
            {

                using (SqlConnection con = DB.NewSqlConnection())
                {
                    con.Open();
                    using (IDataReader reader = DB.GetRSFormat(con, "SELECT Quantity, UnitMeasureCode, CartType FROM EcommerceShoppingCart with (NOLOCK) WHERE ShoppingCartRecGuid = '{0}'", kitCartID))
                    {
                        if (reader.Read())
                        {
                            initialQuantity = DB.RSFieldDecimal(reader, "Quantity");
                            unitMeasureCode = DB.RSField(reader, "UnitMeasureCode");
                        }
                    }
                }

                // make ready our delegate method
                script.AppendFormat("    var delResetUnitMeasure = function(p) {{\n");
                script.AppendFormat("        p.setUnitMeasure('{0}');\n", unitMeasureCode);
                script.AppendFormat("        p.onCompositionChanged();\n");
                script.AppendFormat("    }}\n");

                // reset the product's unit measure
                // we'll need to check first if the product was already registered on the controller
                // if not, we'll wait for it via an observer
                script.AppendFormat("    if(product){{\n");
                script.AppendFormat("        delResetUnitMeasure(product);\n");
                script.AppendFormat("    }}\n");
                script.AppendFormat("    else{{\n");
                
                // register an observer object to be notified via it's notify function whenever the proper product gets registered
                // we'll then use our delegate for that                
                script.AppendFormat("        var umObserver = {{ \n");
                script.AppendFormat("                              notify: function(product){{ \n");
                script.AppendFormat("                                           if(product.getId() == {0}) {{\n", itemCounter);
                script.AppendFormat("                                               delResetUnitMeasure(product);\n");
                script.AppendFormat("                                           }} \n");
                script.AppendFormat("                                       }} \n");
                script.AppendFormat("                          }};\n");
                script.AppendFormat("        ise.Products.ProductController.addObserver(umObserver);\n");
                script.AppendFormat("    }}\n");
            }

            script.AppendFormat("    var qControl = new ise.Products.QuantityControl({0}, 'ctrlQuantity_{0}', {1});\n", itemCounter, initialQuantity);
            script.AppendFormat("    qControl.setProduct(product);\n");
            script.AppendFormat("    frm.setQuantityControl(qControl);\n");

            if (!hideUnitMeasure)
            {
                script.AppendFormat("    var umControl = new ise.Products.UnitMeasureControl({0}, 'ctrlUnitMeasure_{0}');\n", itemCounter);
                script.AppendFormat("    umControl.setProduct(product);\n");
            }

            script.Append(" }\n");
            script.Append(");\n");
            script.Append("</script>\n");
            script.AppendLine();

            output.Append(script.ToString());
            return output.ToString();
        }

        /// <summary>
        /// This is used to automatically invoke the design from xmlpackage
        /// </summary>
        public string DisplayAddToCartForm(int itemCounter, string itemCode, string itemType, string align, bool useXmlDesign)
        {
            ItemWebOption settings = null;
            if (TempWebOptionSettings == null) { settings = ItemWebOption.GetWebOption(itemCode); }
            else { settings = TempWebOptionSettings; }

            //Check for wholesale parameter.
            //Hide add to cart buttons if CBMode is true
            if (!AppLogic.AppConfigBool("ShowBuyButtons") ||
                (AppLogic.AppConfigBool("WholesaleOnlySite") && ThisCustomer.DefaultPrice.ToLower() != "wholesale") || 
                AppLogic.IsCBNMode())
            {
                settings.ShowBuyButton = false;
            }

            var xml = new XElement(DomainConstants.XML_ROOT_NAME);
            xml.Add(new XElement(DomainConstants.XML_SECTION_TYPE, XMLSectionType.DISPLAY_ADDTOCARTFORM));
            xml.Add(new XElement("ITEM_TYPE", itemType));
            xml.Add(new XElement("ITEM_COUNTER", itemCounter));
            xml.Add(new XElement("SKIN_ID", ThisCustomer.SkinID));

            xml.Add(new XElement("SHOW_BUY_BUTTON", settings.ShowBuyButton));
            xml.Add(new XElement("IS_WHOLESALE_ONSITE", AppLogic.AppConfigBool("WholesaleOnlySite")));
            xml.Add(new XElement("IS_CUSTOMER_DEFAULT_PRICE_NOT_WHOLESALE", ThisCustomer.DefaultPrice.ToLower() != "wholesale"));

            bool? enabledGiftRegistry = AppLogic.AppConfigBool("GiftRegistry.Enabled");
            if (ThisCustomer.GiftRegistries.Count() > 0 && (enabledGiftRegistry.HasValue && enabledGiftRegistry.Value))
            {
                bool showGiftRegistry = (enabledGiftRegistry.Value && ThisCustomer.IsRegistered);
                xml.Add(new XElement("SHOW_GIFTREGISTRY_BUTTON", showGiftRegistry.ToStringLower()));

                var customerGiftRegistries = ThisCustomer.GiftRegistries;
                customerGiftRegistries.ForEach(item =>
                {
                    var registries = new XElement("REGISTRIES");
                    registries.Add(new XElement("TEXT", item.Title));
                    registries.Add(new XElement("VALUE", item.RegistryID.ToString().ToLower()));
                    xml.Add(registries);
                });
            }

            if (settings.IsCallToOrder)
            {
                xml.Add(new XElement("CALL_TO_ORDER_TEXT", AppLogic.GetString("common.cs.20", ThisCustomer.SkinID, ThisCustomer.LocaleSetting)));
            }

            if (itemType == Interprise.Framework.Base.Shared.Const.ITEM_TYPE_ELECTRONIC_DOWNLOAD)
            {
                // don't allow file to be downloaded if not yet mapped
                var download = DownloadableItem.FindByItemCode(itemCode);
                if (download == null || !download.IsPhysicalFileExisting())
                {
                    xml.Add(new XElement("NO_AVAILABLE_DOWNLOAD_TEXT", AppLogic.GetString("shoppingcart.cs.39", ThisCustomer.SkinID, ThisCustomer.LocaleSetting)));
                }

                //Per defect #75; If the customer is anonymous don't allow them to buy downloadable items.
                if (ThisCustomer.IsNotRegistered)
                {
                    xml.Add(new XElement("CUSTOMER_NOT_REGISTERED_TEXT", AppLogic.GetString("shoppingcart.cs.40", ThisCustomer.SkinID, ThisCustomer.LocaleSetting)));
                }
            }

            var output = new StringBuilder();
            string action = string.Empty;

            if (settings.RequiresRegistration && ThisCustomer.IsNotRegistered)
            {
                action = MakeItemLink(itemCode);
            }
            else
            {
                action = "addtocart.aspx?returnurl={0}".FormatWith((CommonLogic.GetThisPageName(false) + "?" + CommonLogic.ServerVariables(DomainConstants.QUERY_STRING)).ToUrlEncode());
            }

            xml.Add(new XElement("FORM_ACTION", action));

            bool itemTypeIsKitAndWeAreInEditMode = false;
            var kitCartID = Guid.Empty;

            if (itemType == Interprise.Framework.Base.Shared.Const.ITEM_TYPE_KIT)
            {
                using (var con = DB.NewSqlConnection())
                {
                    con.Open();
                    using (var reader = DB.GetRSFormat(con, "SELECT PricingType FROM InventoryKit with (NOLOCK) WHERE ItemKitCode = {0}", DB.SQuote(itemCode)))
                    {
                        if (reader.Read())
                        {
                            string pricingType = DB.RSField(reader, "PricingType");
                            xml.Add(new XElement("KIT_PRICING_TYPE", pricingType));
                        }
                    }
                }

                string kitCartIDFromQueryString = CommonLogic.QueryStringCanBeDangerousContent("kcid");
                // check if we are in edit mode for this kit item
                if (!CommonLogic.IsStringNullOrEmpty(kitCartIDFromQueryString) &&
                    CommonLogic.IsValidGuid(kitCartIDFromQueryString))
                {
                    itemTypeIsKitAndWeAreInEditMode = true;
                    kitCartID = new Guid(kitCartIDFromQueryString);

                    xml.Add(new XElement("ITEM_KIT_IS_EDITMODE", itemTypeIsKitAndWeAreInEditMode));
                    xml.Add(new XElement("KIT_CART_ID", kitCartID));
                }
            }

            bool hideUnitMeasure = AppLogic.AppConfigBool("HideUnitMeasure");
            xml.Add(new XElement("SHOW_MEASURE", !hideUnitMeasure));
            if (settings.ShowBuyButton)
            {
                if (itemTypeIsKitAndWeAreInEditMode)
                {
                    xml.Add(new XElement("EDITCART_BUTTON_CAPTION", AppLogic.GetString("shoppingcart.cs.33", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true)));
                }
                else
                {
                    xml.Add(new XElement("ADDTOCART_BUTTON_CAPTION", AppLogic.GetString("AppConfig.CartButtonPrompt", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true)));
                }
            }

            xml.Add(new XElement("SHOWWISHLISTBUTTON", AppLogic.AppConfigBool("ShowWishListButton").ToStringLower()));
            xml.Add(new XElement("WISHLIST_CAPTION", AppLogic.GetString("AppConfig.WishButtonPrompt", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true)));

            bool ignoreStockLevel = AppLogic.AppConfigBool("Inventory.LimitCartToQuantityOnHand");

            var jSONAddToCartParamDTO = new JSONAddToCartParamDTO
            {
                ItemCounter = itemCounter,
                ItemCode = itemCode,
                AttributeNotAvailableText = AppLogic.GetString("showproduct.aspx.29", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true),
                ProductNoEnuoughStockText = AppLogic.GetString("showproduct.aspx.30", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true),
                QuantityText = AppLogic.GetString("showproduct.aspx.31", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true),
                UnitMeasureText = AppLogic.GetString("showproduct.aspx.32", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true),
                OrderLessThanText = AppLogic.GetString("showproduct.aspx.36", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true),
                NoEnoughStockText = AppLogic.GetString("showproduct.aspx.42", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true),
                SelectedItemNoEnoughStockText = AppLogic.GetString("showproduct.aspx.43", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true),
                NotificationAvailabilityText = AppLogic.GetString("showproduct.aspx.46", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true),
                EnterNoQuantityText = AppLogic.GetString("common.cs.22", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true),
                SpecifyQuantityText = AppLogic.GetString("common.cs.24", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true),
                IgnoreStockLevel = ignoreStockLevel,
                HideUnitMeasure = hideUnitMeasure
            };

            // Edit MOde just for kits
            decimal initialQuantity = 0;
            string unitMeasureCode = string.Empty;

            initialQuantity = GetInitialAddToCartQuantity();

            if (itemTypeIsKitAndWeAreInEditMode)
            {
                using (var con = DB.NewSqlConnection())
                {
                    con.Open();
                    using (var reader = DB.GetRSFormat(con, "SELECT Quantity, UnitMeasureCode, CartType FROM EcommerceShoppingCart with (NOLOCK) WHERE ShoppingCartRecGuid = '{0}'", kitCartID))
                    {
                        if (reader.Read())
                        {
                            initialQuantity = DB.RSFieldDecimal(reader, "Quantity");
                            unitMeasureCode = DB.RSField(reader, "UnitMeasureCode");
                        }
                    }
                }

                jSONAddToCartParamDTO.UnitMeasureCode = unitMeasureCode;
            }

            jSONAddToCartParamDTO.InitialQuantity = initialQuantity;

            string jsonFormat = JSONHelper.Serialize<JSONAddToCartParamDTO>(jSONAddToCartParamDTO);
            xml.Add(new XElement("CART_JSON_SCRIPT", jsonFormat));
            var xmlpackage = new XmlPackage2(this.XmlPackageHelperTemplate, xml);
            return xmlpackage.TransformString();
        }

        #endregion

        #region DisplayStockHint

        public virtual string DisplayStockHint(int itemCounter, string itemCode, string itemtype)
        {
            if (this.IsUsingHelperTemplate && CurrentContext.IsRequestingFromMobileMode(ThisCustomer))
            {
                return DisplayStockHint(itemCounter, itemCode, itemtype, true);
            }

            StringBuilder output = new StringBuilder("");
            bool isDropShip = false;
            bool isSpecialOrder = false;
            bool isCBN = false;
            int cbnItemID = 0;

            if (!AppLogic.AppConfigBool("ShowStockHints") && !AppLogic.AppConfigBool("ShowActualInventory"))
            {
                return output.ToString();
            }

            if (itemtype == Interprise.Framework.Base.Shared.Const.ITEM_TYPE_NON_STOCK ||
                itemtype == Interprise.Framework.Base.Shared.Const.ITEM_TYPE_SERVICE ||
                itemtype == Interprise.Framework.Base.Shared.Const.ITEM_TYPE_ELECTRONIC_DOWNLOAD)
            {
                return output.ToString();
            }

            using (SqlConnection con = DB.NewSqlConnection())
            {
                con.Open();
                using (IDataReader reader = DB.GetRSFormat(con, "SELECT IsDropShip, IsSpecialOrder, IsCBN, CBNItemID FROM InventoryItem with (NOLOCK) WHERE ItemCode=" + DB.SQuote(itemCode)))
                {
                    while (reader.Read())
                    {
                        isDropShip = DB.RSFieldBool(reader, "IsDropShip");
                        isSpecialOrder = DB.RSFieldBool(reader, "IsSpecialOrder");
                        isCBN = DB.RSFieldBool(reader, "IsCBN");
                        cbnItemID = DB.RSFieldInt(reader, "CBNItemID");
                    }
                }
            }

            if (!isDropShip & !isSpecialOrder || (isCBN && !cbnItemID.IsNullOrEmptyTrimmed()))
            {
                output.AppendFormat("<div id=\"pnlStockHint_{0}\" name=\"pnlStockHint_{0}\" >\n", itemCounter);

                if (AppLogic.AppConfigBool("ShowStockHints"))
                {
                    output.AppendFormat("<img id=\"imgStockHint_{0}\" /><span id=\"lblStockHint_{0}\" style=\"visibility: hidden\"></span>", itemCounter);
                }
                else  
                {
                    if (AppLogic.AppConfigBool("ShowActualInventory"))
                    {
                        output.AppendFormat("<span id=\"lblStockHint_{0}\"></span><img id=\"imgStockHint_{0}\" style=\"visibility: hidden\" />", itemCounter);
                    }
                }

                output.Append("</div>\n");

                StringBuilder script = new StringBuilder();
                script.AppendLine();
                script.Append("<script type=\"text/javascript\" language=\"Javascript\" >\n");
                script.Append("$add_windowLoad(\n");
                script.Append(" function() { \n");

                script.AppendFormat("    ise.StringResource.registerString('showproduct.aspx.46', '{0}');\n", AppLogic.GetString("showproduct.aspx.46", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true));
                script.AppendFormat("    ise.StringResource.registerString('showproduct.aspx.47', '{0}');\n", AppLogic.GetString("showproduct.aspx.47", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true));
                script.AppendFormat("    var product = ise.Products.ProductController.getProduct({0});\n", itemCounter);
                script.AppendFormat("    var ctrlStockHint = new ise.Products.StockHintControl({0}, 'imgStockHint_{0}', 'images/instock.png', 'images/outofstock.png');\n", itemCounter);
                script.AppendFormat("    ctrlStockHint.setProduct(product);\n");

                script.Append(" }\n");
                script.Append(");\n");
                script.Append("</script>\n");
                script.AppendLine();
                
                output.Append(script.ToString());
            }
            return output.ToString();
        }

        public virtual string DisplayStockHint(int itemCounter, string itemCode, string itemtype, bool useXmlDesign)
        {
            string output = string.Empty;
            bool isDropShip = false;
            bool isSpecialOrder = false;
            bool isCBN = false;
            int cbnItemID = 0;

            if (!AppLogic.AppConfigBool("ShowStockHints"))
            {
                return output;
            }

            if (itemtype == Interprise.Framework.Base.Shared.Const.ITEM_TYPE_NON_STOCK &&
                itemtype == Interprise.Framework.Base.Shared.Const.ITEM_TYPE_SERVICE &&
                itemtype == Interprise.Framework.Base.Shared.Const.ITEM_TYPE_ELECTRONIC_DOWNLOAD)
            {
                return output;
            }

            using (var con = DB.NewSqlConnection())
            {
                con.Open();
                using (var reader = DB.GetRSFormat(con, "SELECT IsDropShip, IsSpecialOrder, IsCBN, CBNItemID FROM InventoryItem with (NOLOCK) WHERE ItemCode=" + DB.SQuote(itemCode)))
                {
                    while (reader.Read())
                    {
                        isDropShip = DB.RSFieldBool(reader, "IsDropShip");
                        isSpecialOrder = DB.RSFieldBool(reader, "IsSpecialOrder");
                        isCBN = DB.RSFieldBool(reader, "IsCBN");
                        cbnItemID = DB.RSFieldInt(reader, "CBNItemID");
                    }
                }
            }

            if (isDropShip & isSpecialOrder || (isCBN && !cbnItemID.IsNullOrEmptyTrimmed())) return output;

            var xml = new XElement(DomainConstants.XML_ROOT_NAME);
            xml.Add(new XElement(DomainConstants.XML_SECTION_TYPE, XMLSectionType.DISPLAY_STOCKHINT));
            xml.Add(new XElement("ITEM_COUNTER", itemCounter));
            xml.Add(new XElement("SHOW_ACTUAL_INVENTORY", AppLogic.AppConfigBool("ShowActualInventory")));

            var script = new StringBuilder();
            script.AppendLine();
            script.Append("<script type=\"text/javascript\" >\n");
            script.Append("$add_windowLoad(\n");
            script.Append(" function() { \n");
            script.AppendLine("RegisterStockHintsResources('{0}','{1}',{2})".FormatWith(
                                                AppLogic.GetString("showproduct.aspx.46", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true),
                                                AppLogic.GetString("showproduct.aspx.47", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true),
                                                itemCounter));
            script.Append(" }\n");
            script.Append(");\n");
            script.Append("</script>\n");
            script.AppendLine();

            xml.Add(new XElement("STOCKHINTS_SCRIPT", script.ToString()));
            var xmlpackage = new XmlPackage2(this.XmlPackageHelperTemplate, xml);
            return xmlpackage.TransformString();
        }

        #endregion

        #region DisplayPricingLevel

        public virtual string DisplayPricingLevel(int itemCounter, string itemCode, string itemType)
        {
            if (this.IsUsingHelperTemplate && CurrentContext.IsRequestingFromMobileMode(ThisCustomer))
            {
                return DisplayPricingLevel(itemCounter, itemCode, itemType, true);
            }

            ItemWebOption settings = null;
            if (TempWebOptionSettings == null) { settings = ItemWebOption.GetWebOption(itemCode); }
            else { settings = TempWebOptionSettings; }

            if (settings.HidePriceUntilCart)
            {
                return string.Empty;
            }

            if (AppLogic.AppConfigBool("WholesaleOnlySite") &&
                ThisCustomer.DefaultPrice != Interprise.Framework.Base.Shared.Const.BUSINESS_TYPE_WHOLESALE)
            {
                return string.Empty;
            }

            var output = new StringBuilder();

            bool showInline = AppLogic.AppConfigBool("ShowQuantityDiscountTablesInline");

            output.AppendFormat("<div id=\"pnlPricingLevel_{0}\" name=\"pnlPricingLevel_{0}\" >\n", itemCounter);

            // by default let's hide it and make it visible when toggled
            output.AppendFormat("<div id=\"pnlPricingLevelInline_{0}\" name=\"pnlPricingLevelInline_{0}\" style=\"display:none;\" >\n", itemCounter);
            output.Append("</div>\n");

            // by default let's hide it and make it visible when toggled
            output.AppendFormat("<div id=\"pnlPricingLevelPopUp_{0}\" name=\"pnlPricingLevelPopUp_{0}\" style=\"display:none;\" >\n", itemCounter);
            output.AppendFormat(
                "<p><small>{1}<a id=\"lnkPricingLevelPopUp_{0}\" href=\"javascript:void(0);\" >{2}</a></small></p>\n",
                itemCounter,
                AppLogic.GetString("showproduct.aspx.7", ThisCustomer.SkinID, ThisCustomer.LocaleSetting),
                AppLogic.GetString("showproduct.aspx.8", ThisCustomer.SkinID, ThisCustomer.LocaleSetting)
            );
            output.Append("</div>\n");

            output.Append("</div>\n");

            var script = new StringBuilder();
            script.AppendLine();
            script.Append("<script type=\"text/javascript\" language=\"Javascript\" >\n");            
            script.Append("$add_windowLoad(\n");
            script.Append(" function() { \n");

            script.AppendFormat("    ise.StringResource.registerString('showproduct.aspx.7', '{0}');\n", AppLogic.GetString("showproduct.aspx.7", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true));

            script.AppendFormat("    var product = ise.Products.ProductController.getProduct({0});\n", itemCounter);
            script.AppendFormat("    var ctrl = new ise.Products.PricingLevelControl({0}, 'pnlPricingLevel_{0}');\n", itemCounter);
            script.AppendFormat("    ctrl.setShowInline({0});\n", showInline.ToString().ToLowerInvariant());
            script.AppendFormat("    ctrl.setBackColor('{0}');\n", AppLogic.AppConfig("LightCellColor"));
            script.AppendFormat("    ctrl.setProduct(product);\n");

            script.Append(" }\n");
            script.Append(");\n");
            script.Append("</script>\n");
            script.AppendLine();

            output.Append(script.ToString());

            return output.ToString();
        }

        /// <summary>
        /// This is used to automatically invoke the design from xmlpackage
        /// </summary>
        public virtual string DisplayPricingLevel(int itemCounter, string itemCode, string itemType, bool useXmlDesign)
        {
            string output = string.Empty;

            var xml = new XElement(DomainConstants.XML_ROOT_NAME);
            xml.Add(new XElement(DomainConstants.XML_SECTION_TYPE, XMLSectionType.DISPLAY_PRICINGLEVEL));

            var settings = ItemWebOption.GetWebOption(itemCode);
            if (settings.HidePriceUntilCart)
            {
                return string.Empty;
            }

            if (AppLogic.AppConfigBool("WholesaleOnlySite") &&
                ThisCustomer.DefaultPrice != Interprise.Framework.Base.Shared.Const.BUSINESS_TYPE_WHOLESALE)
            {
                return string.Empty;
            }

            bool showInline = AppLogic.AppConfigBool("ShowQuantityDiscountTablesInline");

            xml.Add(new XElement("ITEM_COUNTER", itemCounter));
            xml.Add(new XElement("SHOWINLINE", AppLogic.AppConfigBool("ShowQuantityDiscountTablesInline")));

            string qualifyText = AppLogic.GetString("showproduct.aspx.7", ThisCustomer.SkinID, ThisCustomer.LocaleSetting);
            xml.Add(new XElement("QUALIFY_TEXT", qualifyText));
            xml.Add(new XElement("WHATS_THIS_TEXT", AppLogic.GetString("showproduct.aspx.8", ThisCustomer.SkinID, ThisCustomer.LocaleSetting)));

            var script = new StringBuilder();
            script.AppendLine();
            script.Append("<script type=\"text/javascript\" >\n");
            script.Append("$add_windowLoad(\n");
            script.Append(" function() { \n");

            script.AppendLine("RegisterPricingLevelResources('{0}',{1},'{2}',{3})".FormatWith(
                                    qualifyText,
                                    showInline.ToString().ToLowerInvariant(),
                                    AppLogic.AppConfig("LightCellColor"),
                                    itemCounter));

            script.Append(" }\n");
            script.Append(");\n");
            script.Append("</script>\n");
            script.AppendLine();

            xml.Add(new XElement("PRICINGLEVEL_SCRIPT", script.ToString()));
            var xmlpackage = new XmlPackage2(this.XmlPackageHelperTemplate, xml);
            return xmlpackage.TransformString();
        }

        #endregion

        #region DisplayKitItemOptions

        public string DisplayKitItemOptions(int itemCounter, string itemCode)
        {
            if (this.IsUsingHelperTemplate && CurrentContext.IsRequestingFromMobileMode(ThisCustomer))
            {
                return DisplayKitItemOptions(itemCounter, itemCode, true);
            }

            var output = new StringBuilder();

            var kit = KitItemData.GetKitComposition(ThisCustomer, itemCounter, itemCode);
            if (kit.Groups.Count > 0)
            {

                var kitSettings = ItemWebOption.GetWebOption(itemCode);

                bool shouldDisplayPrice = !kitSettings.HidePriceUntilCart;

                if (AppLogic.AppConfigBool("WholesaleOnlySite") &&
                    ThisCustomer.DefaultPrice != Interprise.Framework.Base.Shared.Const.BUSINESS_TYPE_WHOLESALE)
                {
                    shouldDisplayPrice = false;
                }

                // render layout
                output.Append("<table class=\"KitContainer\" cellpadding=\"6\" cellspacing=\"0\" border=\"0\">\n");
                output.Append("    <tr>\n");
                output.Append("        <td align=\"left\" valign=\"top\">\n");

                //********** Main Kit Contents ************/
                output.AppendFormat("            <table id=\"KitTable_{0}\" class=\"KitTable\" cellpadding=\"6\" cellspacing=\"0\" border=\"0\">\n", itemCounter);
                foreach (var group in kit.Groups)
                {
                    string leftContent = String.Empty;
                    if (group.Type == "Required")
                    {
                        leftContent = "*";
                    }

                    output.AppendFormat("                <tr id=\"KitGroup_{0}\"  class=\"KitTableGroup\" align=\"left\">\n", group.Id);
                    output.AppendFormat("                    <td colspan=\"3\" >\n");
                    output.AppendFormat("                        <span id=\"lblKitGroup_{0}\" class=\"KitGroupHeader\" >{1}</span>\n", group.Id, leftContent + group.Code);
                    output.AppendFormat("                        <img id=\"imgToolTip_{0}\" style=\"cursor: hand; cursor: pointer;\" src=\"skins/skin_{1}/images/helpcircle.gif\" border=\"0\" align=\"absmiddle\" />", group.Id, ThisCustomer.SkinID);
                    output.AppendFormat("                        </span>");
                    output.AppendFormat("                    </td");
                    output.AppendFormat("                </tr>\n");

                    // render each kit items
                    if (group.Type == "Required")
                    {
                        if (group.ControlType == "Single select drop down")
                        {
                            output.AppendFormat("                <tr align=\"left\">\n");

                            string stockHtml = String.Empty;
                            output.AppendFormat("                    <td width=\"20%\" align=\"right\">{0}</td>\n", stockHtml);
                            output.AppendFormat("                    <td colspan=\"2\" width=\"80%\" align=\"left\"><select id=\"KitGroupDropDown_{0}\" width=\"100%\" ></select></td>\n", group.Id);
                            output.AppendFormat("                </tr>\n");

                            //zero the freestock to hide upon page render.
                            group.Items.SelectMany(um => um.UnitMeasures)
                                        .ForEach(unitMeasure =>
                                        {
                                            unitMeasure.freeStock = Decimal.Zero;

                                            if (kitSettings.HidePriceUntilCart || AppLogic.AppConfigBool("WholesaleOnlySite") &&
                                                ThisCustomer.DefaultPrice != Interprise.Framework.Base.Shared.Const.BUSINESS_TYPE_WHOLESALE)
                                            {
                                                unitMeasure.price = Decimal.Zero;
                                                unitMeasure.priceFormatted = String.Empty;
                                                unitMeasure.promotionalPrice = Decimal.Zero;
                                                unitMeasure.promotionalPriceFormatted = String.Empty;
                                            }

                                        });

                        }
                        else
                        {
                            foreach (var item in group.Items)
                            {
                                output.AppendFormat("                <tr align=\"left\">\n");

                                string stockHtml = String.Empty;
                                if (AppLogic.AppConfigBool("ShowStockHints") &&
                                        item.Type != Interprise.Framework.Base.Shared.Const.ITEM_TYPE_ELECTRONIC_DOWNLOAD &&
                                        item.Type != Interprise.Framework.Base.Shared.Const.ITEM_TYPE_SERVICE)
                                {

                                    stockHtml = string.Format("<img src=\"images/{0}.gif\" /> ", (item.UnitMeasures[0].freeStock > Decimal.Zero)? "instock": "outofstock");
                                }
                                output.AppendFormat("                    <td width=\"20%\" align=\"right\">{0}</td>\n", stockHtml);
                                output.AppendFormat("                    <td width=\"50%\" align=\"left\"><input type=\"radio\" name=\"KitGroupRadio_{0}\" id=\"KitItemRadio_{0}_{1}\" value=\"{1}\" {2} /><span id=\"lblKitItem_{0}_{1}\">{3}</span></td>\n", group.Id, item.Id, ((item.IsSelected)? "checked='true'" : String.Empty), item.Name);
                                output.AppendFormat("                    <td width=\"30%\" align=\"left\"><span id=\"PriceDelta_{0}_{1}\" ></span></td>\n", group.Id, item.Id);
                                output.AppendFormat("                </tr>\n");

                                //zero the freestock to hide upon page render.
                                item.UnitMeasures.ForEach(unitMeasure =>
                                {
                                    unitMeasure.freeStock = decimal.Zero;

                                    if (AppLogic.AppConfigBool("WholesaleOnlySite") &&
                                    ThisCustomer.DefaultPrice != Interprise.Framework.Base.Shared.Const.BUSINESS_TYPE_WHOLESALE)
                                    {
                                        unitMeasure.price = decimal.Zero;
                                        unitMeasure.priceFormatted = String.Empty;
                                        unitMeasure.promotionalPrice = Decimal.Zero;
                                        unitMeasure.promotionalPriceFormatted = String.Empty;
                                    }

                                });

                            }
                        }
                    }
                    else if (group.Type == "Multi-Select")
                    {
                        foreach (var item in group.Items)
                        {
                            output.AppendFormat("                <tr align=\"left\">\n");

                            string stockHtml = String.Empty;
                            if (AppLogic.AppConfigBool("ShowStockHints") &&
                                    item.Type != Interprise.Framework.Base.Shared.Const.ITEM_TYPE_ELECTRONIC_DOWNLOAD &&
                                    item.Type != Interprise.Framework.Base.Shared.Const.ITEM_TYPE_SERVICE)
                            {
                                stockHtml = String.Format("<img src=\"images/{0}.gif\" /> ", (item.UnitMeasures[0].freeStock > Decimal.Zero)? "instock": "outofstock");
                            }

                            output.AppendFormat("                    <td width=\"20%\" align=\"right\">{0}</td>\n", stockHtml);
                            output.AppendFormat("                    <td width=\"50%\" align=\"left\"><input type=\"checkbox\" name=\"KitItemCheckBox_{0}_{1}\" id=\"KitItemCheckBox_{0}_{1}\" value=\"{1}\" {2} ><span id=\"lblKitItem_{0}_{1}\">{3}</span></td>\n", group.Id, item.Id, ((item.IsSelected)? "checked=\"true\"": String.Empty), item.Name);
                            output.AppendFormat("                    <td width=\"30%\" align=\"left\"><span id=\"PriceDelta_{0}_{1}\" ></span></td>\n", group.Id, item.Id);

                            output.AppendFormat("                </tr>\n");

                            //zero the freestock to hide upon page render.
                            item.UnitMeasures.ForEach(unitMeasure =>
                            {
                                unitMeasure.freeStock = decimal.Zero;

                                if (kitSettings.HidePriceUntilCart || AppLogic.AppConfigBool("WholesaleOnlySite") &&
                                ThisCustomer.DefaultPrice != Interprise.Framework.Base.Shared.Const.BUSINESS_TYPE_WHOLESALE)
                                {
                                    unitMeasure.price = decimal.Zero;
                                    unitMeasure.priceFormatted = String.Empty;
                                    unitMeasure.promotionalPrice = Decimal.Zero;
                                    unitMeasure.promotionalPriceFormatted = String.Empty;
                                }

                            });
                        }
                    }
                    else // Optional
                    {
                        //Code Optimization
                        bool noneOptionShouldBeDefaultSelected = group.Items.All(grp => !grp.IsSelected);
                        if (group.ControlType == "Single select drop down")
                        {
                            output.AppendFormat("                <tr align=\"left\">\n");

                            string stockHtml = string.Empty;
                            output.AppendFormat("                    <td width=\"20%\" align=\"right\">{0}</td>\n", stockHtml);
                            output.AppendFormat("                    <td colspan=\"2\" width=\"80%\" align=\"left\"><select id=\"KitGroupDropDown_{0}\" width=\"100%\" ></select></td>\n", group.Id);
                            output.AppendFormat("                </tr>\n");

                            //zero the freestock to hide upon page render.
                            group.Items.SelectMany(um => um.UnitMeasures)
                                        .ForEach(unitMeasure =>
                                        {

                                            unitMeasure.freeStock = decimal.Zero;

                                            if (kitSettings.HidePriceUntilCart || AppLogic.AppConfigBool("WholesaleOnlySite") &&
                                                ThisCustomer.DefaultPrice != Interprise.Framework.Base.Shared.Const.BUSINESS_TYPE_WHOLESALE)
                                            {
                                                unitMeasure.price = decimal.Zero;
                                                unitMeasure.priceFormatted = String.Empty;
                                                unitMeasure.promotionalPrice = Decimal.Zero;
                                                unitMeasure.promotionalPriceFormatted = String.Empty;
                                            }

                                        });
                        }
                        else
                        {
                            // Provide None Option
                            output.AppendFormat("                <tr align=\"left\">\n");
                            output.AppendFormat("                    <td width=\"20%\" align=\"right\"></td>\n");
                            output.AppendFormat("                    <td width=\"50%\" align=\"left\"><input type=\"radio\" name=\"KitGroupRadio_{0}\" id=\"KitItemRadio_{0}_None\" value=\"{1}\" {2} /><span id=\"lblKitItem_{0}_{1}\">{3}</span></td>\n", group.Id, 0, ((noneOptionShouldBeDefaultSelected)? "checked=\"true\"": String.Empty), "None");
                            output.AppendFormat("                    <td width=\"30%\" align=\"left\"></td>\n");
                            output.AppendFormat("                </tr>\n");

                            foreach (var item in group.Items)
                            {
                                output.AppendFormat("                <tr align=\"left\">\n");

                                string stockHtml = String.Empty;
                                if (AppLogic.AppConfigBool("ShowStockHints") &&
                                        item.Type != Interprise.Framework.Base.Shared.Const.ITEM_TYPE_ELECTRONIC_DOWNLOAD &&
                                        item.Type != Interprise.Framework.Base.Shared.Const.ITEM_TYPE_SERVICE)
                                {
                                    stockHtml = String.Format("<img src=\"images/{0}.gif\" /> ", ((item.UnitMeasures[0].freeStock > Decimal.Zero)? "instock": "outofstock"));
                                }

                                output.AppendFormat("                    <td width=\"20%\" align=\"right\">{0}</td>\n", stockHtml);
                                output.AppendFormat("                    <td width=\"50%\" align=\"left\"><input type=\"radio\" name=\"KitGroupRadio_{0}\" id=\"KitItemRadio_{0}_{1}\" value=\"{1}\" {2} /><span id=\"lblKitItem_{0}_{1}\">{3}</span></td>\n", group.Id, item.Id, ((item.IsSelected)? "checked=\"true\"": String.Empty), item.Name);
                                output.AppendFormat("                    <td width=\"30%\" align=\"left\"><span id=\"PriceDelta_{0}_{1}\" ></span></td>\n", group.Id, item.Id);
                                output.AppendFormat("                </tr>\n");

                                //zero the freestock to hide upon page render.
                                item.UnitMeasures.ForEach(unitMeasure =>
                                {
                                    unitMeasure.freeStock = decimal.Zero;

                                    if (kitSettings.HidePriceUntilCart || AppLogic.AppConfigBool("WholesaleOnlySite") &&
                                    ThisCustomer.DefaultPrice != Interprise.Framework.Base.Shared.Const.BUSINESS_TYPE_WHOLESALE)
                                    {
                                        unitMeasure.price = decimal.Zero;
                                        unitMeasure.priceFormatted = String.Empty;
                                        unitMeasure.promotionalPrice = Decimal.Zero;
                                        unitMeasure.promotionalPriceFormatted = String.Empty;
                                    }

                                });
                            }
                        }
                    }

                }
                output.Append("            </table>\n");
                output.Append("        </td>\n");

                output.Append("        <td align=\"left\" valign=\"top\">\n");

                /*************************************/
                /* PopUp Section */
                output.AppendFormat("            <div id=\"KitPlaceHolder\" ></div>\n");
                output.AppendFormat("                <div id=\"KitSideBar\" >\n");
                output.AppendFormat("                    <div id=\"KitAddToCartFormHeader\" >{0}</div>\n", AppLogic.GetString("showproduct.aspx.9", ThisCustomer.SkinID, ThisCustomer.LocaleSetting));

                if (shouldDisplayPrice)
                {
                    output.AppendFormat("                    <div id=\"PopUpKitPrice_{0}\" class=\"KitAddToCartFormPricePopUp\" >\n", itemCounter);
                    output.AppendFormat("                        <div><span id=\"PopUpKitPrice_{0}_Price\" ></span></div>\n", itemCounter);
                    output.AppendFormat("                    </div>\n");
                }

                output.AppendFormat("                    <div id=\"pnlKitDetailsMain_{0}\" >\n", itemCounter);
                output.AppendFormat("                        <div id=\"pnlKitDetailsHeader_{0}\" class=\"KitAddToCartFormDetailsHeader\" ><a id=\"lnkKitDetailHeader_{0}\" href=\"javascript:void(0);\" >{1}</a></div>\n", itemCounter, "- Kit Details -");
                output.AppendFormat("                        <div id=\"pnlKitDetails_{0}\" class=\"KitAddToCartFormDetails\" ></div>\n", itemCounter);
                output.AppendFormat("                    </div>\n");

                string addToCartForm = DisplayAddToCartForm(itemCounter, itemCode, Interprise.Framework.Base.Shared.Const.ITEM_TYPE_KIT, "v");
                output.AppendFormat("                    <div id=\"pnlKitAddToCart_{0}\" class=\"KitAddToCartForm\" >{1}</div>\n", itemCounter, addToCartForm);

                output.AppendFormat("                </div>\n");

                output.Append("        </td>\n");
                /*************************************/

                output.Append("    </tr>\n");
                output.Append("</table>\n");

                var script = new StringBuilder();
                script.AppendLine();
                script.Append("<script type='text/javascript'>\n");
                script.Append("    var initKit = \n");
                script.Append(" function() { \n");

                script.AppendFormat("    ise.StringResource.registerString('showproduct.aspx.10', '{0}');\n", AppLogic.GetString("showproduct.aspx.10", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true));
                script.AppendFormat("    ise.StringResource.registerString('showproduct.aspx.11', '{0}');\n", AppLogic.GetString("showproduct.aspx.11", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true));
                script.AppendFormat("    ise.StringResource.registerString('showproduct.aspx.100', '{0}');\n", "Included in Total Price");
                script.AppendFormat("    ise.StringResource.registerString('showproduct.aspx.26', '{0}');\n", AppLogic.GetString("showproduct.aspx.26", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true));
                script.AppendFormat("    ise.StringResource.registerString('showproduct.aspx.27', '{0}');\n", AppLogic.GetString("showproduct.aspx.27", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true));
                script.AppendFormat("    ise.StringResource.registerString('showproduct.aspx.28', '{0}');\n", AppLogic.GetString("showproduct.aspx.28", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true));
                script.AppendFormat("    ise.StringResource.registerString('showproduct.aspx.37', '{0}');\n", AppLogic.GetString("showproduct.aspx.37", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true));
                script.AppendFormat("    ise.StringResource.registerString('showproduct.aspx.38', '{0}');\n", AppLogic.GetString("showproduct.aspx.38", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true));
                script.AppendFormat("    ise.StringResource.registerString('showproduct.aspx.45', '{0}');\n", AppLogic.GetString("showproduct.aspx.45", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true));

                script.AppendFormat("    var kitId = {0};\n", itemCounter);
                script.Append("    var kitProduct = ise.Products.ProductController.getProduct(kitId);\n");
                script.Append("    if(kitProduct == null){\n");
                script.Append("        ise.Products.ProductController.addObserver(\n");
                script.Append("        { \n");
                script.Append("            notify: function(product){\n");
                script.Append("                if(product.getId() == kitId){\n");
                script.Append("                    initKit();\n");
                script.Append("                }\n");
                script.Append("            }\n");
                script.Append("        })\n");
                script.Append("        return;\n");
                script.Append("    }\n");


                int groupIndex = 1;
                foreach (var group in kit.Groups)
                {
                    script.AppendFormat("    new ToolTip('imgToolTip_{0}', 'kitgroup_ToolTip', \"{1}\");\n", group.Id, group.Description.ToJavaScriptEscape());

                    int itemIndex = 1;
                    if (group.Type == "Required")
                    {
                        if (group.ControlType == "Single select drop down")
                        {
                            script.AppendFormat("    var cbo_{0} = new ise.Products.KitDropDownGroupControl({1}, 'KitGroupDropDown_{1}');\n", groupIndex, group.Id);

                            foreach (var item in group.Items)
                            {
                                script.AppendFormat("    var opt_{0}_{1} = new ise.Products.KitDropDownOptionControl(2);\n", groupIndex, itemIndex, item.Id);
                                script.AppendFormat("    var p_{0} = ise.Products.ProductController.getProduct({0});\n", item.Id);
                                script.AppendFormat("    opt_{0}_{1}.setProduct(p_{2});\n", groupIndex, itemIndex, item.Id);
                                script.AppendFormat("    cbo_{0}.registerControl(opt_{0}_{1});\n", groupIndex, itemIndex);
                                itemIndex++;

                                //zero the freestock to hide upon page render.
                                item.UnitMeasures.ForEach(unitMeasure =>
                                {
                                    unitMeasure.freeStock = decimal.Zero;

                                    if (kitSettings.HidePriceUntilCart || AppLogic.AppConfigBool("WholesaleOnlySite") &&
                                    ThisCustomer.DefaultPrice != Interprise.Framework.Base.Shared.Const.BUSINESS_TYPE_WHOLESALE)
                                    {
                                        unitMeasure.price = decimal.Zero;
                                        unitMeasure.priceFormatted = String.Empty;
                                        unitMeasure.promotionalPrice = Decimal.Zero;
                                        unitMeasure.promotionalPriceFormatted = String.Empty;
                                    }

                                });
                            }

                            script.AppendFormat("    cbo_{0}.buildDisplay();\n", groupIndex);
                        }
                        else
                        {
                            foreach (var item in group.Items)
                            {
                                script.AppendFormat("    var rb_{0}_{1} = new ise.Products.KitItemRadioControl({3}, 'KitItemRadio_{2}_{3}');\n", groupIndex, itemIndex, group.Id, item.Id);
                                script.AppendFormat("    var p_{0} = ise.Products.ProductController.getProduct({0});\n", item.Id);
                                script.AppendFormat("    rb_{0}_{1}.setProduct(p_{2});\n", groupIndex, itemIndex, item.Id);
                                if (shouldDisplayPrice)
                                {
                                    script.AppendFormat("    var delta_{0}_{1} = new ise.Products.PriceDeltaControl({1}, 'PriceDelta_{0}_{1}');\n", group.Id, item.Id);
                                    script.AppendFormat("    delta_{0}_{1}.setProduct(p_{1});\n", group.Id, item.Id);
                                }
                                itemIndex++;

                                //zero the freestock to hide upon page render.
                                item.UnitMeasures.ForEach(unitMeasure =>
                                {
                                    unitMeasure.freeStock = decimal.Zero;

                                    if (kitSettings.HidePriceUntilCart || AppLogic.AppConfigBool("WholesaleOnlySite") &&
                                    ThisCustomer.DefaultPrice != Interprise.Framework.Base.Shared.Const.BUSINESS_TYPE_WHOLESALE)
                                    {
                                        unitMeasure.price = decimal.Zero;
                                        unitMeasure.priceFormatted = String.Empty;
                                        unitMeasure.promotionalPrice = Decimal.Zero;
                                        unitMeasure.promotionalPriceFormatted = String.Empty;
                                    }

                                });
                            }
                        }
                    }
                    else if (group.Type == "Multi-Select")
                    {
                        foreach (var item in group.Items)
                        {
                            script.AppendFormat("    var chk_{0}_{1} = new ise.Products.KitItemCheckBoxControl({3}, 'KitItemCheckBox_{2}_{3}');\n", groupIndex, itemIndex, group.Id, item.Id);
                            script.AppendFormat("    var p_{0} = ise.Products.ProductController.getProduct({0});\n", item.Id);
                            script.AppendFormat("    chk_{0}_{1}.setProduct(p_{2});\n", groupIndex, itemIndex, item.Id);
                            if (shouldDisplayPrice)
                            {
                                script.AppendFormat("    var delta_{0}_{1} = new ise.Products.PriceDeltaControl({1}, 'PriceDelta_{0}_{1}');\n", group.Id, item.Id);
                                script.AppendFormat("    delta_{0}_{1}.setProduct(p_{1});\n", group.Id, item.Id);
                            }
                            itemIndex++;

                            //zero the freestock to hide upon page render.
                            item.UnitMeasures.ForEach(unitMeasure =>
                            {
                                unitMeasure.freeStock = decimal.Zero;

                                if (kitSettings.HidePriceUntilCart || AppLogic.AppConfigBool("WholesaleOnlySite") &&
                                ThisCustomer.DefaultPrice != Interprise.Framework.Base.Shared.Const.BUSINESS_TYPE_WHOLESALE)
                                {
                                    unitMeasure.price = decimal.Zero;
                                    unitMeasure.priceFormatted = String.Empty;
                                    unitMeasure.promotionalPrice = Decimal.Zero;
                                    unitMeasure.promotionalPriceFormatted = String.Empty;
                                }

                            });
                        }
                    }
                    else //Optional
                    {
                        //Code Optimization
                        bool noneOptionShouldBeDefaultSelected = group.Items.All(grp => !grp.IsSelected);
                        script.AppendFormat("    var grp_{0} = kitProduct.getGroup({0});\n", group.Id);
                        script.AppendFormat("    var p_{0}_None = new ise.Products.KitProductNoneItem({1});\n", group.Id, noneOptionShouldBeDefaultSelected.ToStringLower());
                        script.AppendFormat("    p_{0}_None.setGroup(grp_{0});\n", group.Id);

                        if (group.ControlType == "Single select drop down")
                        {
                            script.AppendFormat("    var cbo_{0} = new ise.Products.KitDropDownGroupControl({1}, 'KitGroupDropDown_{1}');\n", groupIndex, group.Id);

                            script.AppendFormat("    var opt_{0}_None = new ise.Products.KitDropDownOptionControl(1);\n", group.Id, 0);
                            script.AppendFormat("    opt_{0}_None.setProduct(p_{0}_None);\n", group.Id);
                            script.AppendFormat("    cbo_{0}.registerControl(opt_{1}_None);\n", groupIndex, group.Id);

                            foreach (KitItem item in group.Items)
                            {
                                script.AppendFormat("    var opt_{0}_{1} = new ise.Products.KitDropDownOptionControl(2);\n", groupIndex, itemIndex, item.Id);
                                script.AppendFormat("    var p_{0} = ise.Products.ProductController.getProduct({0});\n", item.Id);
                                script.AppendFormat("    opt_{0}_{1}.setProduct(p_{2});\n", groupIndex, itemIndex, item.Id);
                                script.AppendFormat("    cbo_{0}.registerControl(opt_{0}_{1});\n", groupIndex, itemIndex);
                                itemIndex++;

                                //zero the freestock to hide upon page render.
                                item.UnitMeasures.ForEach(unitMeasure =>
                                {
                                    unitMeasure.freeStock = decimal.Zero;

                                    if (kitSettings.HidePriceUntilCart || AppLogic.AppConfigBool("WholesaleOnlySite") &&
                                    ThisCustomer.DefaultPrice != Interprise.Framework.Base.Shared.Const.BUSINESS_TYPE_WHOLESALE)
                                    {
                                        unitMeasure.price = decimal.Zero;
                                        unitMeasure.priceFormatted = String.Empty;
                                        unitMeasure.promotionalPrice = Decimal.Zero;
                                        unitMeasure.promotionalPriceFormatted = String.Empty;
                                    }

                                });
                            }

                            script.AppendFormat("    cbo_{0}.buildDisplay();\n", groupIndex);
                        }
                        else
                        {
                            script.AppendFormat("    var rb_{0}_None = new ise.Products.KitItemRadioControl(0, 'KitItemRadio_{0}_None');\n", group.Id);
                            script.AppendFormat("    rb_{0}_None.setProduct(p_{0}_None);\n", group.Id);

                            foreach (var item in group.Items)
                            {
                                script.AppendFormat("    var rb_{0}_{1} = new ise.Products.KitItemRadioControl({3}, 'KitItemRadio_{2}_{3}');\n", groupIndex, itemIndex, group.Id, item.Id);
                                script.AppendFormat("    var p_{0} = ise.Products.ProductController.getProduct({0});\n", item.Id);
                                script.AppendFormat("    rb_{0}_{1}.setProduct(p_{2});\n", groupIndex, itemIndex, item.Id);

                                if (shouldDisplayPrice)
                                {
                                    script.AppendFormat("    var delta_{0}_{1} = new ise.Products.PriceDeltaControl({1}, 'PriceDelta_{0}_{1}');\n", group.Id, item.Id);
                                    script.AppendFormat("    delta_{0}_{1}.setProduct(p_{1});\n", group.Id, item.Id);
                                }

                                itemIndex++;

                                //zero the freestock to hide upon page render.
                                item.UnitMeasures.ForEach(unitMeasure =>
                                {
                                    unitMeasure.freeStock = decimal.Zero;

                                    if (kitSettings.HidePriceUntilCart || AppLogic.AppConfigBool("WholesaleOnlySite") &&
                                    ThisCustomer.DefaultPrice != Interprise.Framework.Base.Shared.Const.BUSINESS_TYPE_WHOLESALE)
                                    {
                                        unitMeasure.price = decimal.Zero;
                                        unitMeasure.priceFormatted = String.Empty;
                                        unitMeasure.promotionalPrice = Decimal.Zero;
                                        unitMeasure.promotionalPriceFormatted = String.Empty;
                                    }

                                });
                            }
                        }
                    }
                }

                if (shouldDisplayPrice) // should toggle if hide price until cart
                {
                    script.AppendFormat("    var ctrlPrice = new ise.Products.KitPriceControl({0}, 'PopUpKitPrice_{0}');\n", itemCounter);
                    script.AppendFormat("    ctrlPrice.setKitProduct(kitProduct);\n");
                }

                script.AppendFormat("    var ctrlDetails = new ise.Products.KitDetailsControl({0});\n", itemCounter);
                script.AppendFormat("    ctrlDetails.setKitProduct(kitProduct);\n");

                // float the sidebar
                script.AppendFormat("    floatKitSideBar();\n");

                script.Append(" }\n");
                script.Append("$add_windowLoad(initKit);\n");
                script.Append("</script>\n");
                script.AppendLine();

                output.Append(script.ToString());

            }
            else
            {
                output.Clear();

                output.Append("<div id='kit-details-not-set'>");
                output.Append(AppLogic.GetString("showproduct.aspx.49", ThisCustomer.SkinID, ThisCustomer.LocaleSetting));
                output.Append("</div>");
            }

            return output.ToString();
        }

        /// <summary>
        /// This is used to automatically invoke the design from xmlpackage
        /// </summary>
        public string DisplayKitItemOptions(int itemCounter, string itemCode, bool useXmlDesign)
        {
            var xml = new XElement(DomainConstants.XML_ROOT_NAME);
            xml.Add(new XElement(DomainConstants.XML_SECTION_TYPE, XMLSectionType.DISPLAY_KIT_DETAILS));
            xml.Add(new XElement("ITEM_COUNTER", itemCounter));

            var output = new StringBuilder();
            var kit = KitItemData.GetKitComposition(ThisCustomer, itemCounter, itemCode);

            var kitSettings = ItemWebOption.GetWebOption(itemCode);
            bool shouldDisplayPrice = !kitSettings.HidePriceUntilCart;

            if (AppLogic.AppConfigBool("WholesaleOnlySite") &&
                ThisCustomer.DefaultPrice != Interprise.Framework.Base.Shared.Const.BUSINESS_TYPE_WHOLESALE)
            {
                shouldDisplayPrice = false;
            }

            xml.Add(new XElement("DISPLAY_PRICE", shouldDisplayPrice.ToString().ToLowerInvariant()));

            if (kit.Groups.Count > 0)
            {

                foreach (var group in kit.Groups)
                {
                    var kitGroup = new XElement("KIT_GROUP_ITEM");

                    string leftContent = string.Empty;
                    if (group.Type == "Required")
                    {
                        leftContent = "*";
                    }

                    kitGroup.Add(new XElement("GROUP_ID", group.Id));
                    kitGroup.Add(new XElement("GROUP_TYPE", group.Type));
                    kitGroup.Add(new XElement("GROUP_TEXT", group.Code));
                    kitGroup.Add(new XElement("CONTROL_TYPE", group.ControlType));

                    // render each kit items
                    if (group.Type == "Required")
                    {
                        if (group.ControlType != "Single select drop down")
                        {
                            foreach (var item in group.Items)
                            {
                                var subGroup = new XElement("SUB_GROUP_ITEM");
                                subGroup.Add(new XElement("SUB_GROUP_ITEM_ID", item.Id));
                                subGroup.Add(new XElement("SKINID", ThisCustomer.SkinID));

                                bool showStockHints = (AppLogic.AppConfigBool("ShowStockHints") &&
                                                        item.Type != Interprise.Framework.Base.Shared.Const.ITEM_TYPE_ELECTRONIC_DOWNLOAD &&
                                                        item.Type != Interprise.Framework.Base.Shared.Const.ITEM_TYPE_SERVICE);

                                bool hasStock = (item.UnitMeasures[0].freeStock > decimal.Zero);
                                subGroup.Add(new XElement("SHOW_STOCKHINTS", showStockHints.ToStringLower()));
                                subGroup.Add(new XElement("HAS_STOCK", hasStock.ToStringLower()));
                                subGroup.Add(new XElement("IS_SELECTED", item.IsSelected.ToStringLower()));
                                subGroup.Add(new XElement("NAME", item.Name));

                                kitGroup.Add(subGroup);
                            }
                        }
                    }
                    else if (group.Type == "Multi-Select")
                    {
                        foreach (var item in group.Items)
                        {
                            var subGroup = new XElement("SUB_GROUP_ITEM");
                            subGroup.Add(new XElement("SUB_GROUP_ITEM_ID", item.Id));
                            subGroup.Add(new XElement("SKINID", ThisCustomer.SkinID));

                            bool showStockHints = (AppLogic.AppConfigBool("ShowStockHints") &&
                                                    item.Type != Interprise.Framework.Base.Shared.Const.ITEM_TYPE_ELECTRONIC_DOWNLOAD &&
                                                    item.Type != Interprise.Framework.Base.Shared.Const.ITEM_TYPE_SERVICE);

                            bool hasStock = (item.UnitMeasures[0].freeStock > decimal.Zero);
                            subGroup.Add(new XElement("SHOW_STOCKHINTS", showStockHints.ToStringLower()));
                            subGroup.Add(new XElement("HAS_STOCK", hasStock.ToStringLower()));
                            subGroup.Add(new XElement("IS_SELECTED", item.IsSelected.ToStringLower()));
                            subGroup.Add(new XElement("NAME", item.Name));
                            kitGroup.Add(subGroup);
                        }
                    }
                    else // Optional
                    {
                        bool noneOptionShouldBeDefaultSelected = true;

                        foreach (var item in group.Items)
                        {
                            if (item.IsSelected)
                            {
                                noneOptionShouldBeDefaultSelected = false;
                                break;
                            }
                        }

                        kitGroup.Add(new XElement("NONEOPTIONSHOULDBEDEFAULTSELECTED", noneOptionShouldBeDefaultSelected.ToStringLower()));
                        if (group.ControlType != "Single select drop down")
                        {
                            foreach (var item in group.Items)
                            {
                                var subGroup = new XElement("SUB_GROUP_ITEM");
                                subGroup.Add(new XElement("SUB_GROUP_ITEM_ID", item.Id));
                                subGroup.Add(new XElement("SKINID", ThisCustomer.SkinID));

                                bool showStockHints = (AppLogic.AppConfigBool("ShowStockHints") &&
                                                        item.Type != Interprise.Framework.Base.Shared.Const.ITEM_TYPE_ELECTRONIC_DOWNLOAD &&
                                                        item.Type != Interprise.Framework.Base.Shared.Const.ITEM_TYPE_SERVICE);

                                bool hasStock = (item.UnitMeasures[0].freeStock > decimal.Zero);
                                subGroup.Add(new XElement("SHOW_STOCKHINTS", showStockHints.ToStringLower()));
                                subGroup.Add(new XElement("HAS_STOCK", hasStock.ToStringLower()));
                                subGroup.Add(new XElement("IS_SELECTED", item.IsSelected.ToStringLower()));
                                subGroup.Add(new XElement("NAME", item.Name));

                                kitGroup.Add(subGroup);
                            }
                        }
                    }

                    xml.Add(kitGroup);
                }

                xml.Add(new XElement("ADDTOCART_HEADER_TEXT", AppLogic.GetString("showproduct.aspx.9", ThisCustomer.SkinID, ThisCustomer.LocaleSetting)));

                string addToCartForm = DisplayAddToCartForm(itemCounter, itemCode, Interprise.Framework.Base.Shared.Const.ITEM_TYPE_KIT, "v", useXmlDesign);
                xml.Add(new XElement("ADDTOCART_FORM", addToCartForm));

                var script = new StringBuilder();
                script.AppendLine();
                script.Append("<script type=\"text/javascript\" >\n");
                script.Append("    var initKit = \n");
                script.Append(" function() { \n");

                script.AppendFormat("    ise.StringResource.registerString('showproduct.aspx.10', '{0}');\n", AppLogic.GetString("showproduct.aspx.10", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true));
                script.AppendFormat("    ise.StringResource.registerString('showproduct.aspx.11', '{0}');\n", AppLogic.GetString("showproduct.aspx.11", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true));
                script.AppendFormat("    ise.StringResource.registerString('showproduct.aspx.100', '{0}');\n", "Included in Total Price");
                script.AppendFormat("    ise.StringResource.registerString('showproduct.aspx.26', '{0}');\n", AppLogic.GetString("showproduct.aspx.26", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true));
                script.AppendFormat("    ise.StringResource.registerString('showproduct.aspx.27', '{0}');\n", AppLogic.GetString("showproduct.aspx.27", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true));
                script.AppendFormat("    ise.StringResource.registerString('showproduct.aspx.28', '{0}');\n", AppLogic.GetString("showproduct.aspx.28", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true));
                script.AppendFormat("    ise.StringResource.registerString('showproduct.aspx.37', '{0}');\n", AppLogic.GetString("showproduct.aspx.37", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true));
                script.AppendFormat("    ise.StringResource.registerString('showproduct.aspx.38', '{0}');\n", AppLogic.GetString("showproduct.aspx.38", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true));
                script.AppendFormat("    ise.StringResource.registerString('showproduct.aspx.45', '{0}');\n", AppLogic.GetString("showproduct.aspx.45", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true));

                script.AppendFormat("    var kitId = {0};\n", itemCounter);
                script.Append("    var kitProduct = ise.Products.ProductController.getProduct(kitId);\n");
                script.Append("    if(kitProduct == null){\n");
                script.Append("        ise.Products.ProductController.addObserver(\n");
                script.Append("        { \n");
                script.Append("            notify: function(product){\n");
                script.Append("                if(product.getId() == kitId){\n");
                script.Append("                    initKit();\n");
                script.Append("                }\n");
                script.Append("            }\n");
                script.Append("        })\n");
                script.Append("        return;\n");
                script.Append("    }\n");

                int groupIndex = 1;
                foreach (var group in kit.Groups)
                {
                    script.AppendFormat("    new ToolTip('imgToolTip_{0}', 'kitgroup_ToolTip', '{1}');\n", group.Id, Security.JavascriptEscape(group.Description));

                    int itemIndex = 1;
                    if (group.Type == "Required")
                    {
                        if (group.ControlType == "Single select drop down")
                        {
                            script.AppendFormat("    var cbo_{0} = new ise.Products.KitDropDownGroupControl({1}, 'KitGroupDropDown_{1}');\n", groupIndex, group.Id);
                            foreach (var item in group.Items)
                            {
                                script.AppendFormat("    var opt_{0}_{1} = new ise.Products.KitDropDownOptionControl(2);\n", groupIndex, itemIndex, item.Id);
                                script.AppendFormat("    var p_{0} = ise.Products.ProductController.getProduct({0});\n", item.Id);
                                script.AppendFormat("    opt_{0}_{1}.setProduct(p_{2});\n", groupIndex, itemIndex, item.Id);
                                script.AppendFormat("    cbo_{0}.registerControl(opt_{0}_{1});\n", groupIndex, itemIndex);
                                itemIndex++;
                            }

                            script.AppendFormat("    cbo_{0}.buildDisplay();\n", groupIndex);
                        }
                        else
                        {
                            foreach (var item in group.Items)
                            {
                                script.AppendFormat("    var rb_{0}_{1} = new ise.Products.KitItemRadioControl({3}, 'KitItemRadio_{2}_{3}');\n", groupIndex, itemIndex, group.Id, item.Id);
                                script.AppendFormat("    var p_{0} = ise.Products.ProductController.getProduct({0});\n", item.Id);
                                script.AppendFormat("    rb_{0}_{1}.setProduct(p_{2});\n", groupIndex, itemIndex, item.Id);
                                if (shouldDisplayPrice)
                                {
                                    script.AppendFormat("    var delta_{0}_{1} = new ise.Products.PriceDeltaControl({1}, 'PriceDelta_{0}_{1}');\n", group.Id, item.Id);
                                    script.AppendFormat("    delta_{0}_{1}.setProduct(p_{1});\n", group.Id, item.Id);
                                }
                                itemIndex++;
                            }
                        }
                    }
                    else if (group.Type == "Multi-Select")
                    {
                        foreach (KitItem item in group.Items)
                        {
                            script.AppendFormat("    var chk_{0}_{1} = new ise.Products.KitItemCheckBoxControl({3}, 'KitItemCheckBox_{2}_{3}');\n", groupIndex, itemIndex, group.Id, item.Id);
                            script.AppendFormat("    var p_{0} = ise.Products.ProductController.getProduct({0});\n", item.Id);
                            script.AppendFormat("    chk_{0}_{1}.setProduct(p_{2});\n", groupIndex, itemIndex, item.Id);
                            if (shouldDisplayPrice)
                            {
                                script.AppendFormat("    var delta_{0}_{1} = new ise.Products.PriceDeltaControl({1}, 'PriceDelta_{0}_{1}');\n", group.Id, item.Id);
                                script.AppendFormat("    delta_{0}_{1}.setProduct(p_{1});\n", group.Id, item.Id);
                            }
                            itemIndex++;
                        }
                    }
                    else //Optional
                    {
                        bool noneOptionShouldBeDefaultSelected = true;
                        foreach (var item in group.Items)
                        {
                            if (item.IsSelected)
                            {
                                noneOptionShouldBeDefaultSelected = false;
                                break;
                            }
                        }

                        script.AppendFormat("    var grp_{0} = kitProduct.getGroup({0});\n", group.Id);
                        script.AppendFormat("    var p_{0}_None = new ise.Products.KitProductNoneItem({1});\n", group.Id, noneOptionShouldBeDefaultSelected.ToString().ToLowerInvariant());
                        script.AppendFormat("    p_{0}_None.setGroup(grp_{0});\n", group.Id);

                        if (group.ControlType == "Single select drop down")
                        {
                            script.AppendFormat("    var cbo_{0} = new ise.Products.KitDropDownGroupControl({1}, 'KitGroupDropDown_{1}');\n", groupIndex, group.Id);

                            script.AppendFormat("    var opt_{0}_None = new ise.Products.KitDropDownOptionControl(1);\n", group.Id, 0);
                            script.AppendFormat("    opt_{0}_None.setProduct(p_{0}_None);\n", group.Id);
                            script.AppendFormat("    cbo_{0}.registerControl(opt_{1}_None);\n", groupIndex, group.Id);

                            foreach (KitItem item in group.Items)
                            {
                                script.AppendFormat("    var opt_{0}_{1} = new ise.Products.KitDropDownOptionControl(2);\n", groupIndex, itemIndex, item.Id);
                                script.AppendFormat("    var p_{0} = ise.Products.ProductController.getProduct({0});\n", item.Id);
                                script.AppendFormat("    opt_{0}_{1}.setProduct(p_{2});\n", groupIndex, itemIndex, item.Id);
                                script.AppendFormat("    cbo_{0}.registerControl(opt_{0}_{1});\n", groupIndex, itemIndex);
                                itemIndex++;
                            }

                            script.AppendFormat("    cbo_{0}.buildDisplay();\n", groupIndex);
                        }
                        else
                        {
                            script.AppendFormat("    var rb_{0}_None = new ise.Products.KitItemRadioControl(0, 'KitItemRadio_{0}_None');\n", group.Id);
                            script.AppendFormat("    rb_{0}_None.setProduct(p_{0}_None);\n", group.Id);

                            foreach (KitItem item in group.Items)
                            {
                                script.AppendFormat("    var rb_{0}_{1} = new ise.Products.KitItemRadioControl({3}, 'KitItemRadio_{2}_{3}');\n", groupIndex, itemIndex, group.Id, item.Id);
                                script.AppendFormat("    var p_{0} = ise.Products.ProductController.getProduct({0});\n", item.Id);
                                script.AppendFormat("    rb_{0}_{1}.setProduct(p_{2});\n", groupIndex, itemIndex, item.Id);

                                if (shouldDisplayPrice)
                                {
                                    script.AppendFormat("    var delta_{0}_{1} = new ise.Products.PriceDeltaControl({1}, 'PriceDelta_{0}_{1}');\n", group.Id, item.Id);
                                    script.AppendFormat("    delta_{0}_{1}.setProduct(p_{1});\n", group.Id, item.Id);
                                }

                                itemIndex++;
                            }
                        }
                    }
                }

                if (shouldDisplayPrice) // should toggle if hide price until cart
                {
                    script.AppendFormat("    var ctrlPrice = new ise.Products.KitPriceControl({0}, 'PopUpKitPrice_{0}');\n", itemCounter);
                    script.AppendFormat("    ctrlPrice.setKitProduct(kitProduct);\n");
                }

                script.AppendFormat("    var ctrlDetails = new ise.Products.KitDetailsControl({0});\n", itemCounter);
                script.AppendFormat("    ctrlDetails.setKitProduct(kitProduct);\n");

                // float the sidebar
                script.AppendFormat("    floatKitSideBar();\n");

                script.Append(" }\n");
                script.Append("$add_windowLoad(initKit);\n");
                script.Append("</script>\n");
                script.AppendLine();

                output.Append(script.ToString());

                xml.Add(new XElement("KIT_SCRIPT", script.ToString()));
            }
            else
            {
                xml.Add(new XElement("KIT_NOT_SET_TEXT", AppLogic.GetString("showproduct.aspx.49", ThisCustomer.SkinID, ThisCustomer.LocaleSetting)));
            }

            var xmlpackage = new XmlPackage2(this.XmlPackageHelperTemplate, xml);
            return xmlpackage.TransformString();
        }

        #endregion

        #region DisplayExpectedShipDate

        public virtual string DisplayExpectedShipDate(int itemCounter, string itemCode, string shippingDate, string itemtype)
        {
            if (this.IsUsingHelperTemplate && CurrentContext.IsRequestingFromMobileMode(ThisCustomer))
            {
                DisplayExpectedShipDate(itemCounter, itemCode, shippingDate, itemtype, true);
            }

            DateTime parsedShippingDate = DateTime.MinValue;
            var output = new StringBuilder();

            if (itemtype == Interprise.Framework.Base.Shared.Const.ITEM_TYPE_NON_STOCK ||
               itemtype == Interprise.Framework.Base.Shared.Const.ITEM_TYPE_SERVICE ||
               itemtype == Interprise.Framework.Base.Shared.Const.ITEM_TYPE_ELECTRONIC_DOWNLOAD)
            {
                return output.ToString();
            }

            //Parse the sqlserver shipping Date giving the sql current locale then convert to customer current culture
            DateTime.TryParseExact(shippingDate,
                        Localization.SqlServerLocaleCulture.DateTimeFormat.GetAllDateTimePatterns(), //sql server current locale
                        ThisCustomer.Culture, //to customer current locale
                        DateTimeStyles.None, 
                        out parsedShippingDate);

            if (parsedShippingDate <= DateTime.Now) { return string.Empty; }

            if (AppLogic.AppConfigBool("ShowShipDateInCart"))
            {
                output.AppendFormat("<div id=\"pnlDisplayExpShipDate_{0}\" class=\"errorLg\" >\n", itemCounter);
                output.AppendFormat(AppLogic.GetString("showproduct.aspx.48", ThisCustomer.SkinID, ThisCustomer.LocaleSetting), Localization.ToNativeShortDateString(parsedShippingDate));
                output.Append("</div>\n");
            }

            return output.ToString();
        }

        public virtual string DisplayExpectedShipDate(int itemCounter, string itemCode, string shippingDate, string itemtype, bool useXmlDesign)
        {
            if (itemtype == Interprise.Framework.Base.Shared.Const.ITEM_TYPE_NON_STOCK ||
               itemtype == Interprise.Framework.Base.Shared.Const.ITEM_TYPE_SERVICE ||
               itemtype == Interprise.Framework.Base.Shared.Const.ITEM_TYPE_ELECTRONIC_DOWNLOAD)
            {
                return string.Empty;
            }

            DateTime parsedShippingDate = DateTime.MinValue;

            //Parse the sqlserver shipping Date giving the sql current locale then convert to customer current culture
            DateTime.TryParseExact(shippingDate,
                        Localization.SqlServerLocaleCulture.DateTimeFormat.GetAllDateTimePatterns(), //sql server current locale
                        ThisCustomer.Culture, //to customer current locale
                        DateTimeStyles.None,
                        out parsedShippingDate);

            if (parsedShippingDate <= DateTime.Now) { return string.Empty; }
            string expextedDateText = AppLogic.GetString("mobile.showproduct.aspx.48", ThisCustomer.SkinID, ThisCustomer.LocaleSetting);
            string targetDate = Localization.ToNativeShortDateString(parsedShippingDate);

            var xml = new XElement(DomainConstants.XML_ROOT_NAME);
            xml.Add(new XElement(DomainConstants.XML_SECTION_TYPE, XMLSectionType.DISPLAY_EXPECTEDSHIPDATE));
            xml.Add(new XElement("ITEM_COUNTER", itemCounter));
            xml.Add(new XElement("EXPECTED_DATE_TEXT", expextedDateText));
            xml.Add(new XElement("EXPECTED_DATE", targetDate));

            var xmlpackage = new XmlPackage2(this.XmlPackageHelperTemplate, xml);
            return xmlpackage.TransformString();
        }

        #endregion

        public virtual string GetImagePathBySkinID()
        {
            return string.Format("skins/Skin_{0}/images/", ThisCustomer.SkinID);
        }

        public virtual string GetSkinID()
        {
            return ThisCustomer.SkinID.ToString();
        }

        public string DisplayEntityPageHeaderDescription(string sEntity, int entityCounter, string sEntityCode)
        {
            return DisplayEntityPageHeaderDescription(sEntity, entityCounter, sEntityCode, "medium");
        }

        public string DisplayEntityPageHeaderDescription(string sEntity, int entityCounter, string sEntityCode, string sSize)
        {
            InputValidator IV = new InputValidator("DisplayEntityPageHeaderDescription");
            String entity = IV.ValidateString("Entity", sEntity);
            String entityCode = IV.ValidateString("EntityCode", sEntityCode);
            String size = IV.ValidateString("Size", sSize);

            StringBuilder output = new StringBuilder();

            string imgPath = AppLogic.LocateImageUrl(entity, entityCounter, size);

            EntityHelper m_EntityHelper = AppLogic.LookupHelper(entity);

            XmlNode n = null;                        
            n = m_EntityHelper.m_TblMgr.SetContext(entityCode);                        

            string EntityInstanceDescription;

            if (m_EntityHelper.m_TblMgr.CurrentFieldByLocale(n, "WebDescription", ThisCustomer.LocaleSetting) != string.Empty)
            {
                EntityInstanceDescription = m_EntityHelper.m_TblMgr.CurrentFieldByLocale(n, "WebDescription", ThisCustomer.LocaleSetting);
            }
            else
            {
                EntityInstanceDescription = m_EntityHelper.m_TblMgr.CurrentFieldByLocale(n, "Description", ThisCustomer.LocaleSetting);
            }

            if (AppLogic.ReplaceImageURLFromAssetMgr)
            {
                EntityInstanceDescription = EntityInstanceDescription.Replace("../images", "images");
            }
            String FileDescription = new DescriptionFile(entity, entityCode, ThisCustomer.LocaleSetting, ThisCustomer.SkinID).Contents;
            if (FileDescription.Length != 0)
            {
                EntityInstanceDescription += "<div align=\"left\">" + FileDescription + "</div>";
            }

            if (AppLogic.AppConfigBool("UseParserOnEntityDescriptions"))
            {
                Parser p = new Parser(ThisCustomer.SkinID, ThisCustomer);
                EntityInstanceDescription = p.ReplaceTokens(EntityInstanceDescription);
            }

            if (AppLogic.AppConfigBool("Force" + entity + "HeaderDisplay") || EntityInstanceDescription.Length != 0)
            {

                if (EntityInstanceDescription.Length != 0 && imgPath.IndexOf("nopicture") == -1)
                {
                    string strAltText = m_EntityHelper.m_TblMgr.CurrentFieldByLocale(n, "SEAltText", ThisCustomer.LocaleSetting);
                    //output.Append(string.Concat("<img align=\"left\" src=\"", imgPath, "\" border=\"0\" alt=\"", strAltText, "\">"));
                    output.Append(string.Concat("<img id=\"imgEntity_" + sEntity + "\"" + " data-contentEntityType=\"" + sEntity + "\" data-contentCounter='" + entityCounter + "' data-contentKey=\"" + sEntityCode + "\" class=\"content\" data-contentType=\"image\" align=\"left\" src=\"", imgPath, "\" border=\"0\" alt=\"", strAltText, "\">"));
                }

                output.Append("<span class=\"parent-category\">" + AppLogic.GetEntityName(entity, entityCode, ThisCustomer.LocaleSetting) + "</span>");
                if (EntityInstanceDescription.Length != 0)
                {
                    output.Append("<span class=\"category-separator\">: </span> <span class=\"sub-category\">" + EntityInstanceDescription +"</span>");
                }
            }

            return output.ToString();
        }

        public string GetCustomerLastGatewayErrorMessage()
        {
            return ThisCustomer.LastGatewayErrorMessage;
        }

        /// <summary>
        /// Renders the search form validation script using our validation framework
        /// </summary>
        /// <param name="formID"></param>
        /// <param name="searchTextID"></param>
        /// <returns></returns>
        public string GetSearchFormValidatorScript(string formId, string searchTextId)
        {
            StringBuilder script = new StringBuilder();
            script.Append(@"
                <script type='text/javascript' Language='JavaScript'>

				function attachValidators(formId, searchTextId) {
				    var requiredMsg = '!SEARCH_TEXT_REQUIRED_ERROR_MESSAGE!';
				    var minLength = !SEARCH_TEXT_MIN_LENGTH!;
				    var minLengthMsg = '!SEARCH_TEXT_MIN_LENGTH_ERROR_MESSAGE!';

                    var funcTrim = function(s){ return s.replace(/^\s+/, '').replace(/\s+$/, '');};

					var form = document.getElementById(formId);

                    if(form) {
                        form.onsubmit = function(){
                            var txt = document.getElementById(searchTextId);
                            var val = funcTrim(txt.value);

                            if(val == '') {
                                alert(requiredMsg);
                                txt.focus();
                                return false;
                            }

                            if(val.length < minLength) {
                                alert(minLengthMsg);
                                txt.focus();
                                return false;
                            }

                            return true;
                        };
                    }
                }

					$add_windowLoad(function(){attachValidators('!SEARCH_FORM_ID!', '!SEARCH_TEXT_ID!');});
				</script>");

            script.Replace("!SEARCH_FORM_ID!", formId);
            script.Replace("!SEARCH_TEXT_ID!", searchTextId);
            
            string requiredErrorMessage = AppLogic.GetString("search.aspx.4", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true);
            int requiredLength = AppLogic.AppConfigNativeInt("MinSearchStringLength");
            string minLengthErrorMessage = string.Format(AppLogic.GetString("search.aspx.2", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true), requiredLength);

            script.Replace("!SEARCH_TEXT_REQUIRED_ERROR_MESSAGE!", requiredErrorMessage);
            script.Replace("!SEARCH_TEXT_MIN_LENGTH!", requiredLength.ToString());
            script.Replace("!SEARCH_TEXT_MIN_LENGTH_ERROR_MESSAGE!", minLengthErrorMessage);

            return script.ToString();
        }

        #region ProductCompareControl

        public string GetProductInformationTabControl(string pDescription, string pSummary, string pWarranty, string pItemCode)
        {
            return GetProductInformationTabControl(pDescription, pSummary, pWarranty, pItemCode, string.Empty);
        }

        public string GetProductInformationTabControl(string pDescription, string pSummary, string pWarranty, string pItemCode, string pURL)
        {
           
            string returnstring = string.Empty;
            if (!this.IsUsingHelperTemplate) { return returnstring; }
            if (string.IsNullOrEmpty(pItemCode)) { return returnstring; }
            var xml = new System.Xml.Linq.XElement(DomainConstants.XML_ROOT_NAME);
            xml.Add(new System.Xml.Linq.XElement("Description", pDescription));
            xml.Add(new System.Xml.Linq.XElement("Summary", pSummary));
            xml.Add(new System.Xml.Linq.XElement("Warranty", pWarranty));
            xml.Add(new System.Xml.Linq.XElement("ItemCode", pItemCode));
            xml.Add(new System.Xml.Linq.XElement("ProductUrl", pURL));

            var xmlpackage = new XmlPackage2(this.XmlPackageHelperTemplate, xml);
            returnstring = xmlpackage.TransformString();
            return returnstring;
        }

        public string GetProductComparePanel(bool includejavascript)
        {
            return GetProductComparePanel(includejavascript, this.XmlPackageHelperTemplate);
        }

        public string GetProductComparePanel(bool includejavascript, string XmlPackageHelperTemplateName)
        {
            return InterpriseHelper.GetProductCompareXmlPackage(includejavascript, XmlPackageHelperTemplateName);
        }

        public string CreateCompareCheckbox(int itemcounter)
        {
            return  InterpriseHelper.CreateCompareCheckbox(itemcounter,this.XmlPackageHelperTemplate);
        }

        public string GetProductAttributeTable(string pItemCode)
        {
            string returnstring = string.Empty;
            if (string.IsNullOrEmpty(pItemCode)) { return returnstring; }
            if (!this.IsUsingHelperTemplate) { return returnstring; }

            List<XmlPackageParam> addParam = new List<XmlPackageParam> {};
            addParam.Add(new XmlPackageParam("ItemCode", pItemCode));
            var xmlpackage = new XmlPackage2(this.XmlPackageHelperTemplate, addParam);
            returnstring = xmlpackage.TransformString();
            return returnstring;
        }

        public virtual string GetProductImageSource(string sEntity, string sId, string sSize)
        {
            var IV = new InputValidator("GetProductImageSource");
            ProductImage img;
            string entity = IV.ValidateString("Entity", sEntity);
            int id = IV.ValidateInt("ID", sId);
            string size = IV.ValidateString("Size", sSize);

            img = ProductImage.Locate(entity, id, size);

            if (img == null) { return string.Empty; }

            return img.src;
        }

        public string MakeAddToCartLink(string itemcode)
        {
            ItemWebOption settings = ItemWebOption.GetWebOption(itemcode);
            string action = string.Empty;

            if (settings.RequiresRegistration && ThisCustomer.IsNotRegistered)
            {
                action = MakeItemLink(itemcode.ToString());
            }
            else
            {
                action = "addtocart.aspx?returnurl=" + CommonLogic.GetThisPageName(false) + "&" + "ProductID =" + itemcode + "& SEName =" + SE.GetEntitySEName("Product", itemcode);
            }

            return action;
        }

        #endregion

        //XML package helper template name
        //Populated during call of XmlPackage2
        //value will be the <XmlHelperPackage name=""> from node of an xmlpagckage(ex simpleproduct.xml.config)
        //Located after the query node
        public string XmlPackageHelperTemplate 
        { 
            get
            {
                string sXmlPackage = XmlPackageHelperTemplateList.ElementAt(XmlPackageHelperTemplateIndex);
                XmlPackageHelperTemplateIndex = 0;
                return sXmlPackage;
            } 
        }

        public int XmlPackageHelperTemplateIndex { get; set; }

        public IEnumerable<string> XmlPackageHelperTemplateList { get; set; }

        private bool IsUsingHelperTemplate
        {
            get
            {
                return (XmlPackageHelperTemplateList != null && XmlPackageHelperTemplateList.Count() > 0);
            }
        }

        public string LocateEntityImage(string entity, int entityCounter, string size)
        {
            var IV = new InputValidator("DisplayEntityPageHeaderDescription");
            entity = IV.ValidateString("Entity", entity);
            size = IV.ValidateString("Size", size);
            return AppLogic.LocateImageUrl(entity, entityCounter, size);
        }

        public virtual void SetXmlPackageHelperTemplate(string index)
        {
            var IV = new InputValidator("SetXmlPackageHelperTemplate");
            XmlPackageHelperTemplateIndex = IV.ValidateInt("Index", index);
        }

        public string GetMobileSearchFormValidatorScript(string formId, string searchTextId)
        {
            StringBuilder script = new StringBuilder();
            script.Append(@"
                <script type='text/javascript'>
				    $(document).ready(function(){
                        attachValidators('!SEARCH_FORM_ID!', '!SEARCH_TEXT_ID!','!SEARCH_TEXT_MIN_LENGTH_ERROR_MESSAGE!','!SEARCH_TEXT_MIN_LENGTH!', '!SEARCH_TEXT_MIN_LENGTH_ERROR_MESSAGE!');
                    });
				</script>");

            script.Replace("!SEARCH_FORM_ID!", formId);
            script.Replace("!SEARCH_TEXT_ID!", searchTextId);

            string requiredErrorMessage = AppLogic.GetString("search.aspx.4", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true);
            int requiredLength = AppLogic.AppConfigNativeInt("MinSearchStringLength");
            string minLengthErrorMessage = string.Format(AppLogic.GetString("search.aspx.2", ThisCustomer.SkinID, ThisCustomer.LocaleSetting, true), requiredLength);

            script.Replace("!SEARCH_TEXT_REQUIRED_ERROR_MESSAGE!", requiredErrorMessage);
            script.Replace("!SEARCH_TEXT_MIN_LENGTH!", requiredLength.ToString());
            script.Replace("!SEARCH_TEXT_MIN_LENGTH_ERROR_MESSAGE!", minLengthErrorMessage);

            return script.ToString();
        }

        public virtual string RenderProductMatrixOptions(int itemCounter, string itemCode, string itemType)
        {
            StringBuilder tmpS = new StringBuilder();
            try
            {
                using (SqlConnection con = DB.NewSqlConnection())
                {
                    con.Open();
                    using (IDataReader reader = DB.GetRSFormat(con, "SELECT MatrixItemCode, MatrixItemDescription, MatrixItemName, Counter FROM InventoryMatrixItem with (NOLOCK) WHERE ItemCode = {0} AND Selected = 1", DB.SQuote(itemCode)))
                    {

                        int i = 1;
                        string row = string.Empty;

                        int stock = 0;
                        string stockImage = string.Empty;

                        while (reader.Read())
                        {

                            string matrixItemCode = DB.RSField(reader, "MatrixItemCode");
                            string matrixItemDescription = DB.RSField(reader, "MatrixItemDescription");

                            string matrixItemName = DB.RSField(reader, "MatrixItemName");
                            Int64 counter  = DB.RSFieldInt(reader, "Counter");

                            stock = InterpriseHelper.InventoryFreeStock(matrixItemCode, ThisCustomer);

                            row = "odd";

                            if (i % 2 == 0) row = "even";
       
                            if (AppLogic.AppConfigBool("ShowActualInventory"))
                            {
                                stockImage = stock.ToString();
                            }
                            else
                            {

                                if (stock > 0)
                                {
                                    stockImage = "<img  src= 'images/instock.png'/>";
                                }
                                else
                                {
                                    stockImage = "<img src= 'images/outofstock.png'/>";
                                }

                            }

                            ProductImage img = ProductImage.Locate("Product", matrixItemCode, "medium");

                            var unitOfMeasurements = ProductPricePerUnitMeasure.GetAll(matrixItemCode, ThisCustomer);

                            StringBuilder tmpUOM = new StringBuilder();

                            foreach (var uom in unitOfMeasurements)
                            {

                                tmpUOM.Append(uom.code + "+" + uom.description);
                                tmpUOM.Append(",");

                            }

                            tmpUOM.Append("endUOM");

                            string itemDescription = string.Empty;

                            if (matrixItemDescription.Length > 30)
                            {

                                itemDescription = string.Format("<a href='javascript:void(1)' onClick='getProductOptionImage(\"{0}::{1}::{2}\")' title='{3}'>{4}...</a>", matrixItemCode, img.src, tmpUOM, matrixItemDescription, matrixItemDescription.Substring(0, 30));

                            }
                            else
                            {
                                itemDescription = string.Format("<a href='javascript:void(1)' onClick='getProductOptionImage(\"{0}::{1}::{2}\")'>{3}</a>", matrixItemCode, img.src, tmpUOM, matrixItemDescription);

                            }


                            tmpS.AppendFormat("<div  class='matrix-item-option matrix-row-alt-{0}'>", row, matrixItemCode);

                            bool ignoreStockLevel = AppLogic.AppConfigBool("Inventory.LimitCartToQuantityOnHand");
                            string disabledOption = string.Empty;

                            if (stock == 0 && ignoreStockLevel)
                            {
                                tmpS.AppendFormat(string.Empty);

                            }
                            else
                            {
                                 tmpS.AppendFormat("<input id='option-{0}' type='radio' value='{0}::{3}' onClick='getProductOptionImage(\"{0}::{1}::{2}\")' name='product-option' {4}>", matrixItemCode, img.src, tmpUOM, counter, disabledOption);
                            }
                            
                          
                            tmpS.Append("</div>");

                            tmpS.AppendFormat("<div class='matrix-item-description matrix-row-alt-{1}'>{0}</div>", itemDescription, row);
                            tmpS.AppendFormat("<div class='matrix-item-price matrix-row-alt-{1}'>{0}</div>", this.GetProductPrice(matrixItemCode, true), row);
                            tmpS.AppendFormat("<div class='matrix-item-status matrix-row-alt-{1}'>{0}</div>", stockImage, row);

                            tmpS.Append("<div class='matrix-list-breaker'></div>");

                            i++;
                        }

                        tmpS.AppendFormat("<div class='hidden' id='quantity-reg-ex'>{0}</div>", CommonLogic.IIF(AppLogic.IsAllowFractional, AppLogic.AllowedQuantityWithDecimalRegEx(ThisCustomer.LocaleSetting), AppLogic.AllowedQuantityWithNoDecimalRegEx(ThisCustomer.LocaleSetting)).Replace("\\", "\\\\"));

                    }

                }
            }
            catch (Exception ex)
            {

                tmpS.Append(ex.Message);

            }

            return tmpS.ToString();

        }

        public virtual bool IsInEditingMode()
        {
            return Customer.Current.IsInEditingMode() && Security.IsAdminCurrentlyLoggedIn();
        }

    }

}







